Android经典应用程序开发
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.4 屏幕切换

在一般情况下,Android的每一个屏幕基本上是一个活动(Activity),屏幕之间的切换实际上就是在活动间互相调用的过程,在程序中通过使用Intent完成屏幕跳转的动作。

Android屏幕跳转的关系和方式如图2-8所示。

图2-8 屏幕跳转的关系和方式

从程序的角度,屏幕之间“切换”的过程实际上是一个屏幕启动了另外一个屏幕。从一个Activity启动另外一个Activity的结果是“跳转”,也就是“屏幕的切换”。在Android中有如下两种类型的跳转。

startActivity():简单启动一个屏幕;

startActivityForResult():以带有返回结果的方式启动一个屏幕。

另外一个方面,如果A屏幕(活动)启动B屏幕之后,自己退出,那么这将是一个没有返回的跳转;如果A屏幕启动B之后,自己没有退出,那么B退出的时候可能又返回到A,这就是一个可返回的跳转。显然,只有在启动者没有退出的情况下,才有返回结果接收的问题。

2.4.1 启动活动的方法

Activity等类继承自Context,Context中的startActivity()方法用于启动一个简单的活动,如下所示:

        public void startActivity (Intent intent)

Intent用于传递两个屏幕之间的信息,实现屏幕的跳转功能。调用者可以通过Intent传递参数,也可以获得跳转对象的返回信息。Android中的各个屏幕一般是对等的,具有启动关系的两个屏幕没有运行时的依赖关系。

本示例是一个简单的屏幕之间的跳转,从一个屏幕跳转到另一个屏幕,在启动第二个屏幕后,前一个屏幕消失。

示例程序:Forward(ApiDemo=>App=>Activity=>Forward)

源代码:

              com/example/android/apis/app/Forward.java
              com/example/android/apis/app/ForwardTarget.java

本示例包含了两个活动,在UI上它们就是两个屏幕,分别为跳转的源和目的,它们在AndroidManifest.xml中的定义如下所示。

        <activity android:name=".app.Forwarding"
                  android:label="@string/activity_forward ding">
            <intent-filter>
                  <action android:name="android.intent.action.MAIN" />
                  <category android:name="android.intent.category.SAMPLE_CODE" />
            </intent-filter>
        </activity>
        <activity android:name=".app.ForwardTarget">  </activity>

两个活动的名称分别为Forwarding和ForwardTarget,由于第二个活动没有intent-filter,因此在程序中只能由第一个活动来启动。

Forwarding程序的运行结果如图2-9所示。

图2-9 活动的跳转程序运行结果(左Forward;右ForwardTarget)

在第一个活动(Forwarding)启动后,单击“Go”按钮跳转到第二个活动(ForwardTarget)。第二个活动退出后,不会返回到第一个活动。

跳转的核心内容在Java源文件Forward.java的以下片段中处理:

        public void onClick(View v)
        {
            Intent intent = new Intent();                          // 建立Intent
            intent.setClass(Forwarding.this, ForwardTarget.class);//在Intent中设置活动目标
            startActivity(intent);
            finish();                                               // 结束当前活动
        }

启动第二个活动需要使用Intent,在其setClass()方法中设置源和返回的内容,Intent是android.content包中的类,用于启动活动、服务或者消息接收器。

这里使用的Intent的setClass()方法的原型如下所示:

        Intent  setClass(Context packageContext, Class<?> cls)

第一个参数是当前的上下文类型Context,因此把当前的活动设置过去即可(Activity本身继承了Context),第二个参数是Intent所包含的Java类,直接设置ForwardTarget.class类即可。

本例中使用了finish()方法表示当前的活动结束,这样在第二个活动(ForwardTarget)启动时,第一个活动(Forward)已经不存在了。如果没有调用finish()方法,第二个活动启动时,第一个活动就会进入停止状态,onPause()和onStop()方法将被接连调用。当第二个活动退出后,第一个活动重新出现,也就是会调用其中的onStart()和onResume()方法。

2.4.2 带有返回结果的启动活动

在某些时候,从跳转的对象返回时,跳转源屏幕需要得到其返回的结果,这样两个屏幕可实现一些交互的效果。

Activity中的以下几个方法运动启动带有返回结果的跳转,如下所示:

        public void startActivityForResult (Intent intent, int requestCode)
        public void  finishActivity(int requestCode)
        protected void onActivityResult (int requestCode, int resultCode, Intent data)

startActivityForResult()可以取得返回结果的活动启动方法;finishActivity()用于结束一个使用startActivityForResult()启动的活动;onActivityResult()用于接收被启动的Activity返回的结果。

提示:上述几个方法只能在Activity中使用,启动者和被启动者之间有所关联。

一个被以startActivityForResult()方式启动的活动,可以使用setResut()方法设置内容给其启动者:

        public void setResut(int resultCode, Intent intent)

按照这种模式,在Activity的启动者和被启动者之间,进行传递的数据有如下4个。

启动Intent:由启动者传递给被启动者,含义和没有返回结果的启动相同;

请求码(int类型):由启动者传递给自己;

返回码(int类型):由被启动者传递给启动者;

返回数据(Intent类型):由被启动者传递给启动者。

后三个也就是启动者的onActivityResult()中所接收的三个参数,其中返回码有以下的Activity类的几个默认数值:

        public static final int RESULT_OK           // -1
        public static final int RESULT_FIRST_USER   // 0
        public static final int RESULT_CANCELED    // 1

以下程序用于一个带有返回结果的活动。

参考示例程序:ReceiveResult(ApiDemo => App=>Activity=>ReceiveResult)

源代码:

              com/example/android/apis/app/ReceiveResult.java
              com/example/android/apis/app/SendResult.java

ReceiveResult程序的运行结果如图2-10所示。

图2-10 带有返回结果的跳转运行结果(左:ReceiveResult;中:SendResult;右:ReceiveResult)

初始化界面如图2-10中左图所示,单击“Get Result”按钮将跳转到第二个屏幕,如图2-10中的中图所示;在第二个屏幕中单击“Corky”和“Violet”按钮将返回第一个屏幕,如图2-10中的右图所示。右图中显示的也就是返回结果的内容。

Java源文件ReceiveResult.java的代码片段如下所示:

        static final private int GET_CODE = 0;
            private OnClickListener mGetListener = new OnClickListener() {
              public void onClick(View v) {
                    Intent intent = new Intent(ReceiveResult.this, SendResult.class);
                    startActivityForResult (intent, GET_CODE); // 带有返回结果的跳转
            }
        };

这里调用的是startActivityForResult()方法,设置一个GET_CODE为请求代码,这样可以获得目标活动的返回信息。这个方法的原型为:

        public void startActivityForResult (Intent intent, int requestCode)

被跳转的目标Java源文件SendResult.java的代码片段如下所示:

        private OnClickListener mCorkyListener = new OnClickListener()
        {
            public void onClick(View v)
            {
              setResult(RESULT_OK,(new Intent()).setAction("Corky!"));// 设置返回结果
              finish();                     // 结束SendResult
            }
        };
        private OnClickListener mVioletListener = new OnClickListener()
        {
            public void onClick(View v)
            {
              setResult(RESULT_OK,(new Intent()).setAction("Violet!"));// 设置返回结果
              finish();                // 结束SendResult
            }
        };

被跳转的目标程序将返回值返回,这里使用的依然是Intent作为交互的信息,通过setAction()设置不同的活动。

由于被跳转的目标程序是被显示Intent调用起来的,因此,返回后继续由ReceiveResult.java对返回值进行处理。返回的信息通过重新实现Activity的onActivityResult()方法来实现,两个整数类型的参数requestCode和resultCode分别代表请求代码和结果码,第三个参数Intent(类型data)表示活动间交互附加的数据信息。

        @Override
        protected void onActivityResult(int requestCode,
                                          int resultCode, Intent data) {
            if (requestCode == GET_CODE) {
              Editable text = (Editable)mResults.getText();
              if (resultCode == RESULT_CANCELED) {      // 处理程序使用回退按键返回的情况
                  text.append("(cancelled)");
              } else {                                    // 处理程序使用setResut()返回的情况
                  text.append("(okay ");
                  text.append(Integer.toString(resultCode));
                  text.append(") ");
                  if (data != null) {
                      text.append(data.getAction());      // 将设置返回数据的动作
                  }
              }
              text.append("\n");
            }
        }

这里onActivityResult()是一个被继承的方法,其参数data就是这个活动接收到的返回结果,data.getAction()可以从返回的Intent中取回内容。

参数requestCode对应于调用startActivityForResult()的时候启动活动时指定的申请码。其作用在于,一个活动启动了多个活动的时候,根据这个requestCode可以区分是哪一个活动返回了。参数resultCode比较特殊,当把启动的程序自己返回的时候,这个数值可以由被启动的程序设置。如果被启动的程序被使用回退按键返回,那么这个数值将为RESULT_CANCELED(0)。

对于resultCode,虽然其类型是整型,但是由于它有几个默认值(Activity类中定义的-1,0,1)用于处理特殊情况,因此,如果用其表示自定义的结果,它只能表示枚举类型,不足以表示整数类型的数据(会和特殊情况有冲突)。更多的返回结果,应该通过Intent来表示。