• 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();
                }
            });
        }
    }
    
    欢迎关注我的专属博客http://dyleaf.cn/
  • 相关阅读:
    使用javaDate类代数据仓库维度表
    Hermes和开源Solr、ElasticSearch 不同
    MapReduce 异常 LongWritable cannot be cast to Text
    吐槽CSDN编辑
    Codeforces 452A Eevee
    看不清楚未来,请做好如今
    JDBC数据库连接
    mixpanel实验教程(2)
    使用jquery+一般处理程序异步载入信息
    Eclipse中的Maven项目报Unbound classpath variable错误
  • 原文地址:https://www.cnblogs.com/Dyleaf/p/7679826.html
Copyright © 2020-2023  润新知