Activity讲解

Activity

Activity 是 Android 应用的重要组成单元之一(另外三个是 Service、BroadcastReceiver 和 ContentProvider),而 Activity 又是 android 应用最常见的组件之一。前面看到的示例通常都只包含一个 Activity,但在实际应用中这个是不太可能的,往往包括多个 Activity,不同的 Activity 向用户呈现不同的操作界面。android 应用的多个 Activity 组成 Activity 栈,当前活动的 Activity 位于栈顶。

建立、配置和使用 Activity

  • 建立自己的 Activity 也需要继承 Activity 基类。当然,在不同应用场景下,有时也要求继承 Activity 的子类。例如,如果应用程序界面只包括列表,则可以让应用程序继承 ListActivity;如果应用程序界面需要实现标签页效果,则可以让应用程序继承 TabActivity。

  • Activity 类间接或直接地继承了 Context、ContextWrapper、ContextThemeWrapper 等基类,因此 Activity 可以直接调用它们的方法。

  • 创建一个 Activity 也需要实现一个或多个方法,其中最常见的就是实现 onCreate(Bundle status)方法,该方法将会在 Activity 创建时被回调,该方法调用 Activity 的 setContentView(View view)方法来显示要展现的 View。为了管理应用程序界面的各组件,调用 Activity 的 findViewById(int id)方法来获取程序界面中的组件,接下来修改各组件的属性和方法即可。

  • 实例讲解

    • 下面以安卓疯狂讲义中的例子来进行讲述
    • 实例:用 LauncherActivity 开发启动 Activity 的列表

LauncherActivity 继承了 ListActivity,因此它本质上也是一个开发列表界面的 Activity,但它开发出来的列表界面与普通列表界面有所不同。它开发出来的列表界面中每个列表项都对应一个 Intent,因此当用户单击不同的列表项时,应用程序会自动启动对应的 Activity。

使用 LauncherActivity 的方法并不难,由于依然是一个 ListActivity,因此同样需要为它设置 Adapter—-即可使用简单的 ArrayAdapter,也可使用 SimpleAdapter,当然还可以扩展 BaseAdapter 来实现自己的 Adapter。与使用普通 ListActivity 不同的是,继承 LauncherActivity 时通常应该重写 Intent intentForPosition(int position)方法,该方法根据不同列表项返回不同的 Intent(用于启动不同的 Activity)

public class MainActivity extends LauncherActivity {
    //定义两个Activity的名称
    String[] names = {"设置程序参数", "查看星际兵种"};
    //定义两个Activity对应的实现类
    Class<?>[] clazzs = {PreferenceActivityTest.class
            , ExpandableListActivityTest.class};

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, names);
        // 设置该窗口显示的列表所需的Adapter
        setListAdapter(adapter);
    }

    //根据列表项返回指定Activity对应的Intent
    @Override
    public Intent intentForPosition(int position) {
        return new Intent(MainActivity.this, clazzs[position]);
    }
}

上面程序还用到了如下两个 Activity

  1. ExpandableListActivityTest:它是 ExpandableListActivity 的子类,用于显示一个可展开的列表窗口。
  2. PreferenceActivityTest:它是 PreferenceActivity 的子类,用于显示一个显示设置选项参数并进行保存的窗口。
  • 实例:使用 ExpandableListActivity 实现可展开的 Activity

ExpandableListActivity 的用法与前面介绍的 ExpandableListView 的用法基本相似,只要为该 Activity 传入一个 ExpandableListAdapter 对象即可,接下来 ExpandableListActivity 将会生成一个显示可展开列表的窗口。

public class ExpandableListActivityTest extends ExpandableListActivity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ExpandableListAdapter adapter = new BaseExpandableListAdapter() {
            int[] logos = new int[]
                    {
                            R.drawable.p,
                            R.drawable.z,
                            R.drawable.t
                    };
            private String[] armTypes = new String[]
                    {"神族兵种", "虫族兵种", "人族兵种"};
            private String[][] arms = new String[][]
                    {
                            {"狂战士", "龙骑士", "黑暗圣堂", "电兵"},
                            {"小狗", "刺蛇", "飞龙", "自爆飞机"},
                            {"机枪兵", "护士MM", "幽灵"}
                    };

            //获取指定组位置、指定子列表项处的子列表项数据
            @Override
            public Object getChild(int groupPosition, int childPosition) {
                return arms[groupPosition][childPosition];
            }

            @Override
            public long getChildId(int groupPosition, int childPosition) {
                return childPosition;
            }

            @Override
            public int getChildrenCount(int groupPosition) {
                return arms[groupPosition].length;
            }

            private TextView getTextView() {
                AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT, 64);
                TextView textView = new TextView(ExpandableListActivityTest.
                        this);
                textView.setLayoutParams(lp);
                textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
                textView.setPadding(36, 0, 0, 0);
                textView.setTextSize(20);
                return textView;
            }

            //该方法决定每个子选项的外观
            @Override
            public View getChildView(int groupPosition, int childPosition,
                                     boolean isLastChild, View convertView, ViewGroup parent) {
                TextView textView = getTextView();
                textView.setText(getChild(groupPosition, childPosition).
                        toString());
                return textView;
            }

            //获取指定组位置处的组数据
            @Override
            public Object getGroup(int groupPosition) {
                return armTypes[groupPosition];
            }

            @Override
            public int getGroupCount() {
                return armTypes.length;
            }

            @Override
            public long getGroupId(int groupPosition) {
                return groupPosition;
            }

            //该方法决定每个组选项的外观
            @Override
            public View getGroupView(int groupPosition, boolean isExpanded,
                                     View convertView, ViewGroup parent) {
                LinearLayout ll = new LinearLayout(
                        ExpandableListActivityTest.this);
                ll.setOrientation(LinearLayout.HORIZONTAL);
                ImageView logo = new ImageView(
                        ExpandableListActivityTest.this);
                logo.setImageResource(logos[groupPosition]);
                ll.addView(logo);
                TextView textView = getTextView();
                textView.setText(getGroup(groupPosition).toString());
                ll.addView(textView);
                return ll;
            }

            @Override
            public boolean isChildSelectable(int groupPosition,
                                             int childPosition) {
                return true;
            }

            @Override
            public boolean hasStableIds() {
                return true;
            }
        };
        // 设置该窗口显示列表
        setListAdapter(adapter);
    }
}

配置 Activity

  • android 应用要求所有应用程序组件(Activity、Service、ContentProvider、BroadcastReceiver)都必须显式进行配置。
  • 只要为< application…/ >元素添加< activity… >子元素即可配置 Activity。例如如下的配置片段:
<activity android:name=".SampleActivity"
    android:icon="@drawable/small_pic.png"
    android:label="@string/freneticLabel"
    android:exported="true"
    android:launchMode="singleInstance"
  • 从上面的配置片段可以看出,配置 Activity 时通常指定如下几个属性。
  1. name:指定该 Activity 的实现类的类名。
  2. icon:指定该 Activity 对应的图标。
  3. label:指定该 Activity 的标签。
  4. exported:指定该 Activity 是否允许被其他应用调用。如果将该属性设为 true,那么该 Activity 将可以被其他应用调用。
  5. launchMode:指定该 Activity 的加载模式,该属性支持 standard、singleTop、singleTask 和 singleInstance 这 4 种加载模式。
  • 除此之外,配置 Activity 时通常还需要指定一个或多个< intent-filter…/ >元素,该元素用于指定 Activity 可响应的 Intent。
  • 为了在 AndroidManifest.xml 文件中配置、管理上面的三个 Activity,可以在清单文件的< application…/ >元素中增加如下三个< activity…/ >子元素。
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.yonga.app" >

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity android:name=".MainActivity"
            android:label="@string/app_name">
            <!-- 指定该Activity是程序的入口 -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!-- 定义两个Activity -->
        <activity android:name=".ExpandableListActivityTest"
            android:label="查看星际兵种">
        </activity>
        <activity android:name=".PreferenceActivityTest"
            android:label="设置程序参数">
        </activity>
    </application>

</manifest>
  • 上面的配置片段配置了三个 Activity,其中第一个 Activity 还配置了一个< intent-filter…/>元素,该元素指定该 Activity 作为应用程序的入口。

启动、关闭 Activity

正如前面所介绍的,一个 android 应用通常都会包含多个 Activity,但只有一个 Activity 会作为程序的入口—-当该 android 应用运行时将会自动启动并执行该 Activity。至于应用中得其他 Activity,通常都由入口 Activity 启动,或由入口 Activity 启动的 Activity 启动。

  • Activity 启动其他 Activity 有如下两个方法。
  1. startActivity(Intent intent):启动其他 Activity。
  2. startActivityForResult(Intent intent,int requestCode):以指定的请求码(requestCode)启动 Activity,而且程序将会获取新启动的 Activity 返回的结果(通过重写 onActivityResult(…)方法来获取)。

启动 Activity 时可指定一个 requestCode 参数,该参数代表了启动 Activity 的请求码,这个请求码的值由开发者根据业务自行设置,用于标识请求来源。

上面两个方法都用到了 Intent 参数,Intent 是 android 应用里各组件之间通信的重要方式。一个 Activity 通过 Intent 来表达自己“意图”—-想要启动哪个组件,被启动的组件即可是 Activity 组件,也可是 Service 组件。

  • android 为关闭 Activity 准备了如下两个方法。
  1. finish():结束当前 Activity。
  2. finishActivity(int requestCode): 结束以 startActivityForResult(Intent intent,int requestCode)方法启动的 Activity。
public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // 获取应用程序中的bn按钮
        Button bn = (Button) findViewById(R.id.bn);
        // 为bn按钮绑定事件监听器
        bn.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View source) {
                // 创建需要启动的Activity对应的Intent
                Intent intent = new Intent(MainActivity.this,
                        SecondActivity.class);
                // 启动intent对应的Activity
                startActivity(intent);
            }
        });
    }
}
public class SecondActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second);
        // 获取应用程序中的previous按钮
        Button previous = (Button) findViewById(R.id.previous);
        // 获取应用程序中的close按钮
        Button close = (Button) findViewById(R.id.close);
        // 为previous按钮绑定事件监听器
        previous.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View source) {
                // 获取启动当前Activity的上一个Intent
                Intent intent = new Intent(SecondActivity.this,
                        MainActivity.class);
                // 启动intent对应的Activity
                startActivity(intent);
            }
        });
        // 为close按钮绑定事件监听器
        close.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View source) {
                // 获取启动当前Activity的上一个Intent
                Intent intent = new Intent(SecondActivity.this,
                        MainActivity.class);
                // 启动intent对应的Activity
                startActivity(intent);
                // 结束当前Activity
                finish();
            }
        });
    }
}
posted @ 2017-10-17 08:38  Dyleaf  阅读(182)  评论(0编辑  收藏  举报