Android 入门(四) | Intent 实现 Activity 切换
文章目錄
- Intent
- 顯式 Intent
- 定義兩個(gè) xml 文件
- android:orientation
- match_parent 和 wrap_content
- Intent函數(shù)
- 定義兩個(gè) Activity
- 隱式 Intent
- 更多隱式 Intent 的用法
- 用隱式 Intent 打開系統(tǒng)瀏覽器
- 自建 Activity 以響應(yīng)打開網(wǎng)頁(yè)的 Intent
- 向下一個(gè)活動(dòng)傳遞數(shù)據(jù)
- 返回?cái)?shù)據(jù)給上一個(gè)活動(dòng)
Intent
如何在切換 Actiity 時(shí)攜帶數(shù)據(jù)是一個(gè)重要問題。我們定義兩個(gè) xml 文件,通過 Intent 實(shí)現(xiàn)在活動(dòng)間跳轉(zhuǎn)。
什么是 xml 文件?
xml 即可擴(kuò)展標(biāo)記語(yǔ)言,是互聯(lián)網(wǎng)數(shù)據(jù)傳輸?shù)闹匾ぞ?#xff0c;它可以跨越互聯(lián)網(wǎng)任何的平臺(tái),在服務(wù)器之間穿梭結(jié)構(gòu)化數(shù)據(jù),不受編程語(yǔ)言和操作系統(tǒng)的限制,可以說它是一個(gè)擁有互聯(lián)網(wǎng)最高級(jí)別通行證的數(shù)據(jù)攜帶者。
xml 用于標(biāo)記電子文件使其具有結(jié)構(gòu)性的標(biāo)記語(yǔ)言,可以用來標(biāo)記數(shù)據(jù)、定義數(shù)據(jù)類型,是一種允許用戶對(duì)自己的標(biāo)記語(yǔ)言進(jìn)行定義的源語(yǔ)言。xml 是標(biāo)準(zhǔn)通用標(biāo)記語(yǔ)言(SGML)的子集,非常適合 Web 傳輸。
Inten啟動(dòng)組件的方法:
| Activity | startActvity() |
| startActivity() | |
| – | – |
| Service | startService() |
| bindService() | |
| – | – |
| Broadcasts | sendBroadcasts() |
| sendOrderedBroadcasts() | |
| sendStickyBroadcasts() |
顯式 Intent
定義兩個(gè) xml 文件
定義一個(gè) first_layout.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:id="@+id/button_1"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="點(diǎn)擊有驚喜~"></Button></LinearLayout>定義一個(gè) second_layout.xml:
<?xml version="1.0" encoding="utf-8"?> <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=".SecondActivity"><Buttonandroid:layout_height="wrap_content"android:layout_width="match_parent"android:id="@+id/button_2"android:text="再點(diǎn)一次~"></Button></LinearLayout>android:orientation
orientation 定義了頁(yè)面組件排列方式是垂直(vertical)還是水平(horizontal)。
match_parent 和 wrap_content
Android 中所有的控件都具有 layout_width 和 layout_height 這兩個(gè)屬性,可選值有3種:match_parent、fill_parent、wrap_content。
其中 match_parent 和 fill_parent 的意義相同,但官方更推薦 match_parent 。
- match_parent 表示讓當(dāng)前控件的大小和父布局的大小一樣,也就是由父布局來決定當(dāng)前控件的大小。
- wrap_content 表示讓當(dāng)前的控件大小能夠剛好包含里面的內(nèi)容,也就是由控件內(nèi)容決定當(dāng)前控件的大小。
Intent函數(shù)
Intent 函數(shù)接收兩個(gè)參數(shù):
- 第一個(gè)參數(shù) Context 為上下文,一般使用 this 即可。
- 第二個(gè)參數(shù)為要啟動(dòng)的目標(biāo) Activity。
函數(shù)內(nèi)部調(diào)用了 ComponentName 函數(shù),該函數(shù)可以啟動(dòng)其他應(yīng)用的 Activity、Service:
- pkg: Activity、Service 所在應(yīng)用的包名。
- cls: Activity、Service 的包名+類名。
定義兩個(gè) Activity
MainActivity:
package com.example.intent_test;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);this.setContentView(R.layout.first_layout);Button button1 = (Button)this.findViewById(R.id.button_1);button1.setOnClickListener((View view)->{// 顯式IntentIntent intent = new Intent(this, SecondActivity.class);this.startActivity(intent);});} }SecondActivity:
package com.example.intent_test;import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button;import androidx.appcompat.app.AppCompatActivity;public class SecondActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);this.setContentView(R.layout.second_layout);Button button2 = (Button)this.findViewById(R.id.button_2);button2.setOnClickListener((View view)->{// 顯式IntentIntent intent = new Intent(this, MainActivity.class);this.startActivity(intent);});} }定義兩個(gè) Activity 之后,我嘗試運(yùn)行時(shí)曾出現(xiàn)報(bào)錯(cuò),原因是修改 AndroidManifest.xml 文件時(shí)不小心刪了一段配置代碼……所以說還是能不碰 AndroidManifest.xml 就不碰它(對(duì)于新手而言),如果有同學(xué)也出現(xiàn)報(bào)錯(cuò),可以參考一下我的 AndroidManifest.xml ,檢查一下自己的是否有問題:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.intent_test"><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.Intenttest"><activity android:name=".SecondActivity"/><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>運(yùn)行結(jié)果:
運(yùn)行 MainActivity:
點(diǎn)擊之后跳轉(zhuǎn):
點(diǎn)擊再點(diǎn)一次后回跳回圖一。
隱式 Intent
在 AndroidManifest.xml 中修改 .SecondActivity 的 activity 屬性:
action 標(biāo)簽指定當(dāng)前活動(dòng)可以響應(yīng) com.example.activitytest.ACTION_START 這個(gè)活動(dòng),而 category 標(biāo)簽包含一些附加信息,表明只有在 action 和 category 中的內(nèi)容同時(shí)匹配上 Intent 的內(nèi)容的時(shí)候,SecondActivity 才可以響應(yīng) Intent 。
在 first_layout.xml 中添加第二個(gè)按鈕,(因?yàn)?Android 布局界面和業(yè)務(wù)邏輯分離,因此本質(zhì)上是在 MainActivity 的頁(yè)面布局上添加 button3):
在 MainActivity 中為 button3 綁定 隱式Intent :
即使不為 Intent 指定 category 標(biāo)簽(未調(diào)用 addCategory()),它也會(huì)在調(diào)用 startActivity() 方法時(shí)自動(dòng)添加默認(rèn)的 category(即 android.intent.category.DEFAULT)。
每個(gè) Intent 中只能指定一個(gè) action,但卻能指定多個(gè) categoryo 。
運(yùn)行結(jié)果:
更多隱式 Intent 的用法
用隱式 Intent 打開系統(tǒng)瀏覽器
指定 Intent.ACTION_VIEW 為 action,這是一個(gè) Android 統(tǒng)內(nèi)置的動(dòng)作,常量值為 android.intent.action.VIEW,然后通過 Uri.parse 方法,解析網(wǎng)址成一個(gè) Uri 對(duì)象,調(diào)用 setDate 將其傳遞進(jìn)去。
setData 方法可以接受一個(gè) Uri 對(duì)象,指定當(dāng)前 Intent 正在操作的數(shù)據(jù)。通常數(shù)據(jù)都是以字符串的形式傳入到 Uri.parse 方法中解析產(chǎn)生。
自建 Activity 以響應(yīng)打開網(wǎng)頁(yè)的 Intent
與之對(duì)應(yīng),我們可以在 <intent-filter> 標(biāo)簽中再配置一個(gè) <data> 標(biāo)簽,用于更加精確地指定當(dāng)前活動(dòng)能夠響應(yīng)什么類型的數(shù)據(jù)。下面是 <data> 標(biāo)簽中可以配置的內(nèi)容:
android:scheme //用于指定數(shù)據(jù)的協(xié)議部分,如http android:host //用于指定數(shù)據(jù)的主機(jī)名部分,如www.baidu.com android:port //用于指定數(shù)據(jù)的端口部分,一般跟隨在主機(jī)名后 android:path //用于指定主機(jī)名和端口之后的部分,如一段網(wǎng)址中跟在域名之后的內(nèi)容 android:mimeType //用于指定可以處理的數(shù)據(jù)類型,允許使用通配符的方式進(jìn)行指定新建 ThirdActivity ,無需添加多余代碼,默認(rèn)樣式即可:
重點(diǎn)在于修改 AndroidManifest.xml 中 ThirdActivity 的配置:
Intent 只有一個(gè) action 標(biāo)簽,但可以有多個(gè) category 標(biāo)簽。
出現(xiàn)該 action 標(biāo)簽必須配置下面的 category 標(biāo)簽,否則會(huì)報(bào)錯(cuò):
<category android:name="android.intent.category.BROWSABLE" />android:scheme 的值由被打開網(wǎng)頁(yè)的 Url 決定:
<data android:scheme="http" />運(yùn)行結(jié)果:
但實(shí)際上通過自定義的 Activity 打開是沒有任何內(nèi)容的,因?yàn)槲覀儧]有配置相應(yīng)的 xml 布局也沒有豐富 ThirdActivity 的邏輯代碼:
向下一個(gè)活動(dòng)傳遞數(shù)據(jù)
兩個(gè) Activity 之間傳遞數(shù)據(jù)也是使用 Intent,通過 putExtra() 方法的重載,可以把我們想要傳遞的數(shù)據(jù)暫存在 Intent 中,啟動(dòng)了另一個(gè)活動(dòng)之后,只需要把這些數(shù)據(jù)再?gòu)?Intent 中取出就可以了。
- Intent.putExtra(String name, @Nullable String value) : 向 Intent 中寫入數(shù)據(jù)。
- Intent.getxxxExtra: 向 Intent 中取得數(shù)據(jù)。
MainActivity 中有一個(gè)字符串,現(xiàn)在想把它傳遞到下一個(gè)活動(dòng)當(dāng)中:
然后在 SecondActivity 中取出數(shù)據(jù):
- 首先通過 getIntent 方法獲取到用于啟動(dòng) SecondActivity 的 Intent;
- 然后調(diào)用 getStringExtra 方法,傳入相應(yīng)的鍵值(即消息的名稱),就可以得到相應(yīng)的數(shù)據(jù)了;
- Log.d 用于打印日志以便于尋找 bug;
- .show() 用于顯示 Toast 信息。
Toast.makeText 是 Andriod 的消息模式:
- context:當(dāng)前的上下文環(huán)境。可用 getApplicationContext() 或 this ;
- text:要顯示的字符串。也可是 R.string 中 字符串ID ;
- duration:顯示的時(shí)間長(zhǎng)短。Toast 默認(rèn)的有兩個(gè) LENGTH_LONG 和 LENGTH_SHORT,也可以使用毫秒如 2000ms。
運(yùn)行結(jié)果:
返回?cái)?shù)據(jù)給上一個(gè)活動(dòng)
在 SecondActivity 中構(gòu)建一個(gè) Intent 用于傳遞數(shù)據(jù),然后調(diào)用了 setResult 方法,這個(gè)方法專用于向上一個(gè)活動(dòng)返回?cái)?shù)據(jù),它有兩個(gè)參數(shù):
public final void setResult(int resultCode, Intent data) {synchronized (this) {mResultCode = resultCode;mResultData = data;} }- resultCode:用于向上一個(gè)活動(dòng)返回處理結(jié)果,一般只用 RESULT_OK 或者 RESULT_CANCELED 這兩個(gè)值;
- data:將帶有數(shù)據(jù)的 Intent 傳遞回去。
通過 finish() 方法來銷毀活動(dòng),也可以使用回退鍵銷毀活動(dòng),但要重寫一下 onBackPressed 方法:
接下來實(shí)現(xiàn)對(duì) MainActivity 的編寫:
Activity 中有 startActivityFroResult 方法,也是用于啟動(dòng)活動(dòng)的,且在活動(dòng)銷毀時(shí)返回一個(gè)結(jié)果給上一個(gè)活動(dòng)。該方法接受兩個(gè)參數(shù):
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {startActivityForResult(intent, requestCode, null); }- Intent: 啟動(dòng)的 Activity;
- requestCode: 請(qǐng)求碼,用于在之后的回調(diào)中判斷數(shù)據(jù)來源。
startActivityForResult 方法在 SecondActivity 活動(dòng)銷毀之后會(huì)回調(diào) MainActivity 活動(dòng)的 onActivityResult 方法,因此需要在 MainActivity 中重寫來得到返回的數(shù)據(jù)。onActivityResult 方法有三個(gè)參數(shù):
- 請(qǐng)求碼 requestCode:就是 startActivityForResult 中傳入的 int 值;
- resultCode:返回?cái)?shù)據(jù)時(shí)傳入的處理結(jié)果;
- data:攜帶著返回?cái)?shù)據(jù)的 Intent。
運(yùn)行結(jié)果:
總結(jié)
以上是生活随笔為你收集整理的Android 入门(四) | Intent 实现 Activity 切换的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 剑指offer:55-58记录
- 下一篇: Android在子线程里使用Toast报