速讀原著-Android應用開發入門教程(屏幕間的跳轉和事件的傳遞)
- 2020 年 1 月 16 日
- 筆記
6.4 屏幕間的跳轉和事件的傳遞
在一般情況下,Android 的每一個屏幕基本上就是一個活動(Activity),屏幕之間的切換實際上就是在活動間互相調用的過程,Android 使用 Intent 完成這個動作。
Android 屏幕跳轉的關係和方式如下圖所示:
事實上,在 Android 中,屏幕使用一個活動來實現,屏幕之間是相互獨立的,屏幕之間的跳轉關係通過 Intent來實現。
6.4.1.跳轉的方法
本示例是一個簡單的屏幕之間的跳轉,從一個屏幕跳轉到另一個屏幕,在啟動第二個屏幕後,前一個屏幕消失。
參考示例程序:Forward(ApiDemo => App=>Activity=>Forward)
源代碼:com/example/android/apis/app/Forward.java
com/example/android/apis/app/ForwardTarget.java
布局資源代碼:forward_target.xml 和 forwarding.xml
本示例包含了兩個活動,在 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,因此在程序中只能由第一個活動來啟動。
Forward 程序的運行結果如圖所示:
點擊「Go」按鈕從 Forward 跳轉到 ForwardTarget,這個內容在 Java 源文件 Forward.java 的以下片段中處理:
public void onClick(View v) { Intent intent = new Intent(); // 建立 Intent intent.setClass(Forwarding.this, ForwardTarget.class); // 設置活動 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 狀態,當第二個活動退出後,第一個活動重新出現,也就是會調用活動的 onResume()函數。
6.4.2.帶有返回值的跳轉
在某些時候,從跳轉的對象返回時,跳轉源頭需要得到其返回的結果,這樣兩個屏幕才可實現一些交互。 參考示例程序:ReceiveResult(ApiDemo => App=>Activity=>ReceiveResult)
源代碼:com/example/android/apis/app/ReceiveResult.java
布局資源代碼:receive_result.xml
和 send_result.xml
<activity android:name=".app.ReceiveResult" android:label="@string/activity_receive_result"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.SAMPLE_CODE" /> </intent-filter> </activity> <activity android:name=".app.SendResult"> </activity>
ReceiveResult 程序的運行結果如圖所示:
初始化界面如圖所示,點擊「Get Result」按鈕將跳轉到第二個屏幕,如中圖所示;在第二個屏幕中點擊「Corky」和「Violet」按鈕將返回第一個屏幕,並獲得對應顯示,如右圖所示。
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(); } }; private OnClickListener mVioletListener = new OnClickListener() { public void onClick(View v) { setResult(RESULT_OK, (new Intent()).setAction("Violet!")); finish(); } };
被跳轉的目標程序將返回值返回,這裡使用的依然是 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 { 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()的時候指定的返回值。Android 中使用 Intent 並使用 startActivity()和 startActivityForResult()調用一個新的活動,實現屏幕的跳轉功能,調用者可以獲得跳轉對象的返回信息。