Activity 活动跳转(Java&Kotlin)
在任何正式的APP中,都不可能只有一个Activity。当有多个Activity时,如何从一个Activity进入到另一个Activity呢?答案就是活动跳转。
1. 普通跳转
顾名思义,就是单纯从A到B,不带任何内容。
Java代码:
```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的更复杂啊,这当然不行啊,所以我们可以自己写。
```kotlin
// TestActivity 为要跳转的页面
startActivity
```
就这么简单,不管是从代码上还是从意思上都比Java要简洁明了。要这样使用的话,你的Kotlin需要引入Anko库。首先修改项目的build.gradle,在buildscript里加上:
```groovy
ext.anko_version = '0.10.8'
```
然后修改模块的build.gradle,在dependencies里加上:
```groovy
implementation 'org.jetbrains.anko:anko-common:$anko_version'
```
加完之后Sync同步一样。接着在MainActivity中导入:
```kotlin
import org.jetbrains.anko.startActivity
```
然后就可以直接使用了。
2. 传递数据
实际开发中的页面跳转都不会是单纯的跳转,肯定会携带一些参数的。
Kotlin 代码:
// 传递方 - 通过关键字 to 分隔键与值,前面是键,后面是值。第一种写法
val intent = startActivity
"id" to 456,
"name" to "晨曦"
)
// 接收方 - 通过 intent.extras?.getInt() 和 getString() 获取相对应键的值
val id = intent.extras?.getInt("id")
val name = intent.extras?.getString("name")
在Android开发中,有时需要根据不同情况动态指定页面的启动模式。由于在AndroidManifest.xml文件中,每个Activity只能指定唯一的启动模式,因此不能直接在代码中设置启动模式。但是,Android允许在代码中手动设置启动标志,这样在调用startActivity方法时就可以运行特定的启动模式。
以下是适用于setFlags方法的几种启动标志的取值说明:
1. Intent.FLAG_ACTIVITY_NEW_TASK:开启一个新任务。该值类似于launchMode="standard",但如果原来不存在活动栈,FLAG_ACTIVITY_NEW_TASK 会创建一个新栈。
2. Intent.FLAG_ACTIVITY_SINGLE_TOP:当栈顶为你跳转的Activity实例时,重用栈顶的实例。该值等同于launchMode="singleTop"。
3. Intent.FLAG_ACTIVITY_CLEAR_TOP:当栈顶存在待跳转的Activity实例时,重新创建一个新实例,并将原实例上方的所有实例加以清除。该值与launchMode="singleTask"类似,但launchMode="singleTask"采用onNewIntent启动原任务,而FLAG_ACTIVITY_CLEAR_TOP 采用先onDestroy再onCreate创建新任务。
4. Intent.FLAG_ACTIVITY_NO_HISTORY:该标志与launchMode="standard"情况类似,但栈中不保存新启动的Activity实例。这样下次无论以何种方式启动该实例,也要走standard的完整流程。
5. Intent.FLAG_ACTIVITY_CLEAR_TASK:该标志非常暴力,跳转到新页面时,栈中的原有实例都被清除。注意:该标志要结合FLAG_ACTIVITY_NEW_TASK 使用,即setFlags的参数为“Intent.FLAG_ACTIVITY_CLEAR_TASK”。
启动模式在Java中可能显得有些繁琐,但在Kotlin中,我们可以通过Anko库提供的`intentFor`函数来简化设置启动标志的过程。例如,要设置`FLAG_ACTIVITY_NEW_TASK`启动标志,可以使用以下Anko写法:
```kotlin
startActivity(intent.newTask())
```
这种简洁的方式非常实用。接下来,我们来看一下所有Java方法对应的Anko库的写法。
首先是`Intent`类的启动标志:
1. `FLAG_ACTIVITY_NEW_TASK`:新建任务
2. `FLAG_ACTIVITY_SINGLE_TOP`:置于栈顶
3. `FLAG_ACTIVITY_CLEAR_TOP`:清空栈顶
4. `FLAG_ACTIVITY_NO_HISTORY`:无历史记录
5. `FLAG_ACTIVITY_CLEAR_TASK`:清除任务
然后是Anko库中的标志设置函数:
1. `newTask()`:新建任务
2. `singleTop()`:置于栈顶
3. `clearTop()`:清空栈顶
4. `noHistory()`:无历史记录
5. `clearTask().newTask()`:清除任务后新建一个任务
最后是对应的Java和Kotlin代码:
Java:
```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:
```kotlin
startActivity(intent.newTask()) // 新任务
startActivity(intent.singleTop()) // 置于栈顶
startActivity(intent.clearTop()) // 清空栈顶
startActivity(intent.noHistory()) // 无历史记录
startActivity(intent.clearTask().newTask()) // 清除之后新建一个任务
```
根据提供的内容,重构后的代码如下:
页面跳转分为两种情况:
1. 上一个页面传递请求参数给下一个页面;
2. 上一个页面需要接受下一个页面的返回数据。
在这两种情况下,Kotlin和Java都采用了相同的方法:`startActivityForResult`。下面是用Kotlin和Java实现的示例代码:
Java:
```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:
```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)
}
```