合理组织安卓活动

本文所有代码均存放于https://github.com/MADMAX110/Starbuzz
开始构建一个应用时,你会考虑这个应用要包含什么,会有各种各样的很多想法,如何组织这些想法来建立一个直观、清晰的应用。
一、活动归类
要组织各种各样的活动,有一种方法很有效:可以把它们归类为3种不同类型的活动:顶级活动、类别活动和详细信息/编辑活动
顶级活动:括对用户来说最重要的功能,要为用户提供便捷的途径,使他们能轻松地导航到这些功能。在大多是应用中,用户看到的第一个活动就是顶级活动。
类别活动:会显示某个特定类别的数据,通常会显示在一个列表中。这一类活动一般用于帮助用户导航到详细信息/编辑活动。
详细信息/编辑活动:会显示某个特定记录的详细信息,允许用户编辑这个记录,或者可以让用户输入新的记录。
很显然以上三种活动具有明显的层级关系,存在层层调用的关系。

二、构建一个菜单应用
在顶级活动中,包含一个logo,还会显示一个导航列表,其中包括饮料,食物和分店的入口。
在饮料类别活动中,会显示出售的所有饮料的一个清单。用户单击其中一种,可以查看其更多详细信息。
在饮料详细活动中,会显示饮料名,图片及描述。
由此看来,该应用的应用结构已经非常清晰了。包含三个活动,TopLevelActivity使应用的顶级活动,允许用户在应用中导航。DrinkCategoryActivity是一个类别活动,它包含所有饮料的一个列表。而DrinkActivity会显示某种饮料的详细信息。
应用的工作如下:
1、应用启动时,它会启动活动TopLevelActivity。
该活动使用布局activity_top_level.xml。它会显示一个选项列表,其中包括Drinks、Food和Stores。
2、用户单击TopLevelActivity中的Drinks。这会启动DrinkCategoryActivity。
这个活动使用布局activity_drink_category.xml,会显示一个饮料列表。从Drink.java类文件中获得饮料信息。
3、用户单击DrinkCategoryActivity中的饮料,这会启动DrinkActivity。
这个活动使用布局activity_drink.xml,他也从Drink.java类文件获得饮料的详细信息。

三、创建工程
如下图所示,创建一个名为Starbuzz的新的安卓工程。
合理组织安卓活动_第1张图片
工程目录如下:
合理组织安卓活动_第2张图片
其中包括一个Drink类,三个活动,三个布局,以及四张图片。
工程保存图像时,Android会为各个图像指定一个ID,形式为R.drawable.image_name,值是int类型。

四、Drink类
首先是Drink类,这是一个纯Java类,定义了一个包括3中饮料的数组,每种饮料包括饮料名,描述,以及图像资源ID。
Drink.java

package com.hfad.starbuzz;

public class Drink {
    private String name;
    private String description;
    private int imageResourceId;
    //drinks is an array of Drinks
    public static final Drink[] drinks = {
            new Drink("Latte", "A couple of espresso shots with steamed milk", R.drawable.latte),
            new Drink("Cappuccino", "Espresso, hot milk, and a steamed milk foam", R.drawable.cappuccino),
            new Drink("Filter", "Highest quality beans roasted and brewed fresh", R.drawable.filter)
    };

    //Each Drink has a name, description, and an image resource
    private Drink(String name, String description, int imageResourceId) {
        this.name = name;
        this.description = description;
        this.imageResourceId = imageResourceId;
    }

    public String getDescription() {
        return description;
    }

    public String getName() {
        return name;
    }

    public int getImageResourceId() {
        return imageResourceId;
    }

    public String toString() {
        return this.name;
    }
}

五、顶级布局
TopLevelActivity时默认活动,其布局为activity_top_level.xml。顶级布局包含一个图像和一个列表
定义图像视图:

<ImageView
    android:layout_width="200dp"
    android:layout_height="100dp"
    android:src="@drawable/starbuzz_logo"
    android:contentDescription="@string/starbuzz_logo"
    />

在strings.xml中增加字符串

<string name="starbuzz_logo">Starbuzz logostring>

定义列表视图

    <ListView
        android:id="@+id/list_options"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:entries="@array/options" />

在strings.xml中增加一个字符串数组

    <string-array name="options">
        <item>Drinksitem>
        <item>Fooditem>
        <item>Storesitem>
    string-array>

完整的activity_top_level.xml代码


<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.hfad.starbuzz.TopLevelActivity"
    >

    <ImageView
        android:layout_width="200dp"
        android:layout_height="100dp"
        android:src="@drawable/starbuzz_logo"
        android:contentDescription="@string/starbuzz_logo"
        />

    <ListView
        android:id="@+id/list_options"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:entries="@array/options"
        />
LinearLayout>

实现效果如图所示:
合理组织安卓活动_第3张图片

六、在顶级活动中利用监听器让列表视图响应单击
可以实现一个事件监听器让列表视图中的列表项响应用户单击。
事件监听器允许你监听应用中发生的事件,例如单击视图、视图得到焦点或失去焦点,或者用户按下设备上的一个按键。通过事件监听器可以对用户某个特定的动作做出响应。
使用OnItemClickListener监听列表项的单击事件
下面是完整的TopActivity.java代码

package com.hfad.starbuzz;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;

public class TopLevelActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_top_level);
        //创建监听器
        AdapterView.OnItemClickListener itemClickListener =
                new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                        //Drink是列表视图中的第一项,所以位于位置0
                        if (position == 0) {
                            //这个意图来自TopLevelActivity,需要启动DrinkCategoryActivity
                            Intent intent = new Intent(TopLevelActivity.this, DrinkCategoryActivity.class);
                            startActivity(intent);
                        }
                    }
                };
        //为列表视图增加监听器
        ListView listView = (ListView) findViewById(R.id.list_options);
        listView.setOnItemClickListener(itemClickListener);
    }
}

七、类别活动显示一个类别的数据
DrinkCategoryActivity是类别活动的一个例子。类别活动显示属于某个特定类别的数据,通常会显示在一个列表中。可以使用类别活动导航查看数据的详细信息。
需要注意的是:这里不使用android:entries属性,但是这样只能关联一个静态数组。这里我们需要把列表视图关联到Drink类中的drinks数组。
非静态数据要使用适配器
如果要在列表视图中显示数据,而数据来自strings.xml以外的其他数据源(如一个Java数组或数据库),就需要使用适配器。适配器就像数据源和列表视图之间的一座桥。这里主要使用数组适配器。数组适配器可以将数组和视图绑定,可以用于AdapterView类的任何子类,这说明这种适配器也可以用于列表视图和spinner,ArrayAdapter是一种专门用于处理数组的适配器
用数组适配器连接列表视图和数组:

ArrayAdapter<Drink> listAdapter = new ArrayAdapter<>(
                this,
                android.R.layout.simple_list_item_1,
                Drink.drinks);

数组适配器一般有三个参数,一个Context(通常是当前活动),一个布局资源以及数组本身。
然后关联到列表视图

ListView listDrinks = (ListView) findViewById(R.id.list_drinks);
listDrinks.setAdapter(listAdapter);

处理单击事件

AdapterView.OnItemClickListener itemClickListener = new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (position == 0) {
                    Intent intent = new Intent(DrinkCategoryActivity.this, DrinkCategoryActivity.class);
                    startActivity(intent);
                }
            }
        };

将所单击列表项的ID增加到一个意图来传递ID
用类别活动在一个列表视图中显示列表项,通常会使用onItemClick方法启动另一个活动来显示用户单击的列表项的详细信息。为此,要创建一个意图启动第二个活动。然后为意图增加所单击列表项的ID作为额外信息,使得第二个活动启动时可以使用这个信息。在这里我们希望启动DrinkActivity并传入所选择饮料的ID。然后DrinActivity就能使用这个信息显示相应饮料的详细信息了。下面给出意图的代码:

Intent intent = new Intent(DrinkCategoryActivity.this, DrinkActivity.class);
        //向意图增加所单击列表项的ID,第一个参数表示使用这个常量名表示意图中的额外信息名
        //这样就能知道DrinkCategoryActivity和DrinkActivity在使用同一个字符串
        //创建DrinkActivity活动时要增加这个常量。
        intent.putExtra(DrinkActivity.EXTRA_DRINKID, (int)id);
        startActivity(intent);

完整的DrinkCategoryActivity代码

package com.hfad.starbuzz;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class DrinkCategoryActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_drink_category);
        ArrayAdapter<Drink> listAdapter = new ArrayAdapter<>(
                this,
                android.R.layout.simple_list_item_1,
                Drink.drinks);
        ListView listDrinks = (ListView) findViewById(R.id.list_drinks);
        listDrinks.setAdapter(listAdapter);

        AdapterView.OnItemClickListener itemClickListener = new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (position == 0) {
                    Intent intent = new Intent(DrinkCategoryActivity.this, DrinkCategoryActivity.class);
                    startActivity(intent);
                }
                Intent intent = new Intent(DrinkCategoryActivity.this, DrinkActivity.class);
                //向意图增加所单击列表项的ID,第一个参数表示使用这个常量名表示意图中的额外信息名
                //这样就能知道DrinkCategoryActivity和DrinkActivity在使用同一个字符串
                //创建DrinkActivity活动时要增加这个常量。
                intent.putExtra(DrinkActivity.EXTRA_DRINKID, (int)id);
                startActivity(intent);
            }
        };

       listDrinks.setOnItemClickListener(itemClickListener);
    }
}

八、详细信息活动显示一个记录的数据
activity_drink.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".DrinkActivity">

    <ImageView
        android:id="@+id/photo"
        android:layout_width="190dp"
        android:layout_height="190dp"/>

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@id/description"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
LinearLayout>

从意图获取数据
创建DrinkCategoryActivity时,将用户单击的饮料的ID作为额外信息增加到意图。为它指定一个标签DrinkActivity.EXTRA_DRINKID,要在DrinkActivity中把它定义一个常量:

public static final String EXTRA_DRINKID = "drinkId";

从意图中获取EXTRA_DRINKID值

int drinkId = (Integer)getIntent().getExtras().get(EXTRA_DRINKID);

再使用drinkID得到用户选择的饮料的详细信息,drinkID时饮料的ID。也就是drinks数组中这种饮料的索引,这说明可以使用以下代码得到用户单击的饮料:

Drink drink = Drink.drinks[drinkId];

使用数据更新视图

  TextView name = (TextView) findViewById(R.id.name);
        name.setText(drink.getName());

        TextView description = (TextView) findViewById(R.id.description);
        description.setText(drink.getDescription());

        ImageView photo = (ImageView) findViewById(R.id.photo);
        photo.setImageResource(drink.getImageResourceId());
        photo.setContentDescription(drink.getName());

完整的DrinkActivity代码:

package com.hfad.starbuzz;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;

public class DrinkActivity extends AppCompatActivity {

    public static final String EXTRA_DRINKID = "drinkId";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_drink);

        int drinkId = (Integer)getIntent().getExtras().get(EXTRA_DRINKID);
        Drink drink = Drink.drinks[drinkId];

        TextView name = (TextView) findViewById(R.id.name);
        name.setText(drink.getName());

        TextView description = (TextView) findViewById(R.id.description);
        description.setText(drink.getDescription());

        ImageView photo = (ImageView) findViewById(R.id.photo);
        photo.setImageResource(drink.getImageResourceId());
        photo.setContentDescription(drink.getName());
    }


}

你可能感兴趣的:(Android实践,android,开发语言)