在Android开发中,我们经常有启动一个新的Activity的需求。通常,我们都是通过直接调用Intent(Context packageContext, Class<?> cls)方法构造一个Intent,然后再调用Activity类中的startActivity方法来启用新的Activity,但是,我们有办法使用Kotlin来让这一切变得更简单吗,答案当然是肯定的。
我们知道,在kotlin中我们可以使用inline关键字来创建 一个内联函数,而内联函数有一个很重要的特性就是还可以使用reified来标记一个实化类型参数,这样我们就可以不用传递一个Class引用了,直接传入类型实参即可。另外,由于我们可以一般都是通过Activity来启动一个新的Activity,所以我们可以为Activity创建一个扩展函数,具体代码如下:
inline fun <reified T : Activity> Activity.startActivity() {
val intent = Intent(this, T::class.java)
startActivity(intent)
}
通过使用这个扩展函数,我们启动一个新的Activity就变得简单多了,在一个Activity中调用以下代码即可启动SecondActiivty:
startActivity<SecondActivity>() //没错,只需要这一行代码
但是,上面的代码还存在一些问题,如果我们需要向新启动的Activityl中传递一些参数怎么办?通过上面的方式我们就没办法去操作创建目标Intent了啊。
为了解决这个问题,我们可以对上述扩展函数稍加改进,改进过的函数添加了一个带接收者的lambda表达式:
inline fun <reified T : Activity> Activity.startActivity(intentAction: Intent.() -> Unit = {}) {
val intent = Intent(this, T::class.java)
intent.intentAction()
startActivity(intent)
}
注意到上面的代码我为接收者为Intent的lambda表达式设置了一个默认的空的lambda表达式,这样当我们不需要传递参数时,依然可以像之前一样使用一行代码即可启动一个新的Actiivty。当我们需要传递参数给新的Activity时,我们可以通过传入一个lambda表达式来操作内部创建的Intent:
class ParamsActivity : AppCompatActivity() {
companion object{
private const val EXTRA_KEY_TEXT="ParamsActivity.extra.text"
fun startActivity(activity:Activity,text:String){
activity.startActivity<ParamsActivity> {
putExtra(EXTRA_KEY_TEXT,text)
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_params)
text_view.text=intent.getStringExtra(EXTRA_KEY_TEXT)
}
}
上述伴生对象方法 startActivity(activity:Activity,text:String)
即实现了为启动ParamsActivity的Intent添加一个类型为String的extra内容的功能。
事实上,受制于java的泛型实现,不少地方的函数调用我们都需要传递一个Class实例来传入类型。依靠kotlin的实化类型参数,在不少地方,我们都可以通过类泛型的方式来传入类型,从而免去了Class实例的传入,使代码看起来更简洁,也更具有可读性,推荐大家在合适的地方积极使用实化类型参数来代替Class类型的形参。
本文由 sung 创作,采用 知识共享署名4.0
国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Jun 4,2020