Activity 活動跳轉(Java&Kotlin)
任何正式APP都不可能只有一個Activity,當有多個Activity時,怎麼從一個Activity進入到另一個Activity呢?
答案就是活動跳轉。
① 普通跳轉
顧名思義,就是單純從A到B,不帶任何內容。
Java
//活動跳轉,從MainActivity跳轉到TestActivity,普通跳轉
startActivity(new Intent(MainActivity.this,TestActivity.class));
如果把剛纔Java裏的代碼複製到Kotlin裏,會需要轉譯,轉譯後的Kotlin代碼如下:
Kotlin
//活動跳轉,從MainActivity跳轉到TestActivity,普通跳轉
//MainActivity.this 可以 簡寫成 this
startActivity(Intent(this@MainActivity, TestActivity::class.java))
有沒有感覺這個看起來比Java的更復雜啊,這當然不行啊,所以我們可以自己寫。
//TestActivity 爲要跳轉的頁面
startActivity<TestActivity>()
就這麼簡單,不管是從代碼上還是從意思上都比Java要簡潔明瞭,要這樣使用的話你的Kotlin需要裏引入Anko庫,
第一步
修改項目的build.gradle,在buildscript里加上
ext.anko_version = '0.10.8'
修改模塊的build.gradle,在dependencies里加上
implementation "org.jetbrains.anko:anko-common:$anko_version"
加完之後Sync同步一樣。
然後在MainActivity中導入
import org.jetbrains.anko.startActivity
然後就可以直接使用了。
② 傳遞數據
實際開發中的頁面跳轉都不會是單純的跳轉,肯定會攜帶一些參數的。
Java
//傳遞方
//活動跳轉時傳值 通過鍵值的方式傳遞 另一頁面接收根據鍵來取值
Intent intent = new Intent(this,TestActivity.class);
intent.putExtra("id",456);
intent.putExtra("name","晨曦");
startActivity(intent);
//接收方
//接收int類型數據,使用getIntExtra,如果沒有拿到值則用默認值,
//接收String類型數據,使用getStringExtra,不用默認值.
int id = getIntent().getIntExtra("id",0);
String name = getIntent().getStringExtra("name");
Kotlin
//傳遞方
//通過關鍵字to分隔鍵與值,前面是鍵 後面是 值
//第一種寫法
startActivity<TestActivity>("id" to 456, "name" to "晨曦")
//第二種寫法
//Pair類把參數名和參數值進行配對,這種方式和Java有點像
startActivity<TestActivity>(
Pair("id",456),
Pair("name","晨曦")
)
//接收方
//通過intent.extras?拿到包裹的數據,通過getInt和getString拿到相對應鍵的值
val id = intent.extras?.getInt("id")
val name = intent.extras?.getString("name")
③ 跳轉時指定啓動模式
在代碼中動態指定頁面的啓動模式,因爲在AndroidManifest.xml中對每個Activity只能指定唯一的啓動模式,如果想在不同時候對同一個Activity運用不同的啓動模式,顯然固定的launchMode屬性無法滿足找個需求。所以Android允許在代碼中手動設置啓動表示,這樣在不同時候調用startActivity方法就能運行特定的啓動模式。
適用於setFlags方法的幾種啓動標誌的取值說明如下表:
Intent類的啓動標誌 | 說明 |
---|---|
Intent.FLAG_ACTIVITY_NEW_TASK | 開啓一個新任務,flag默認該值類似於launchMode=“standard”,不同之處在於,如果原來不存在活動棧,FLAG_ACTIVITY_NEW_TASK 就會創建一個新棧 |
Intent.FLAG_ACTIVITY_SINGLE_TOP | 當棧頂爲你跳轉的Activity實例時,重用棧頂的實例。該值等同於launchMode=“singleTop” |
Intent.FLAG_ACTIVITY_CLEAR_TOP | 當棧頂存在待跳轉的Activity實例時,重新創建一個新實例,並將原實例上方的所有實例加以清楚。該值與launchMode="singleTask"類似,但launchMode="singleTask"採用onNewIntent啓動原任務,而FLAG_ACTIVITY_CLEAR_TOP 採用先onDestroy再onCreate創建新任務 |
Intent.FLAG_ACTIVITY_NO_HISTORY | 該標誌與launchMode="standard"情況類似,但棧中不保存新啓動的Activity實例。這樣下次無論以何種方式啓動該實例,也要走standard的完整流程 |
Intent.FLAG_ACTIVITY_CLEAR_TASK | 該標誌非常暴力,跳轉到新頁面時,棧中的原有實例都被情況,注意:該標誌要結合FLAG_ACTIVITY_NEW_TASK 使用,即setFlags的參數爲“Intent.FLAG_ACTIVITY_CLEAR_TASK |
啓動模式在Java中是比較瑣碎的,在Kotlin中則通過Anko庫擴展出來的intentFor函數簡化啓動標誌的設置方式,列如,啓動標誌FLAG_ACTIVITY_NEW_TASK 對應的Anko寫法如下:
startActivity(intent.newTask())
短小精悍
來看一下所有的Java方法對應的Anko庫的寫法
Intent類的啓動標誌 | Anko庫的標誌設置函數 |
---|---|
FLAG_ACTIVITY_NEW_TASK | newTask() |
FLAG_ACTIVITY_SINGLE_TOP | singleTop() |
FLAG_ACTIVITY_CLEAR_TOP | clearTop() |
FLAG_ACTIVITY_NO_HISTORY | noHistory() |
FLAG_ACTIVITY_CLEAR_TASK | clearTask() |
Java
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//新任務
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);//置於棧頂
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);//清空棧頂
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);//歷史
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);//清除之後新建一個任務
Kotlin
startActivity(intent.newTask())//新任務
startActivity(intent.singleTop())//置於棧頂
startActivity(intent.clearTop())//清空棧頂
startActivity(intent.noHistory())//歷史
startActivity(intent.clearTask().newTask())//清除之後新建一個任務
④ 處理返回數據
頁面跳轉的多數情況是上一個頁面傳遞請求參數給下一個頁面,當然也有少數情況是上一個頁面需要接受下一個頁面的返回數據,此時Kotlin和Java一樣都採取startActivityForResult方法,表示這次活動跳轉要求處理返回信息。
Java
@Override
public void startActivityForResult(Intent intent, int requestCode) {
super.startActivityForResult(intent, requestCode);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
Kotlin
override fun startActivityForResult(intent: Intent?, requestCode: Int) {
super.startActivityForResult(intent, requestCode)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
}