Kotlin 扩展函数以 Intent extras 开始 activity
Kotlin extension function start activity with Intent extras
我正在尝试为 Context 编写一个 kotlin 扩展函数,它将在 android 中启动一个新的 activity,并带有给定的 class 名称和意图附加列表。我能够在没有任何额外功能的情况下成功启动 activity,但我遇到了问题。
fun <T> Context.openActivity(it: Class<T>, pairs: List<Pair<String, Any>>) {
var intent = Intent()
pairs.forEach {
intent.putExtra(it.first, it.second)
}
startActivity(intent)
}
Main issue here is -> intent.putExtra() doesn't except second param as
Any
Intent
对象中没有方法 putExtra(String, Any)
。您可以使用 Bundle
对象来保存您的数据:
fun <T> Context.openActivity(it: Class<T>, bundleKey: String, bundle: Bundle) {
var intent = Intent(this, it)
intent.putExtra(bundleKey, bundle)
startActivity(intent)
}
要在 Context
对象中调用它:
val bundle = Bundle()
bundle.putString("Key", "Value") // you can put another object here
openActivity(SomeActivity::class.java, "Bundle Key", bundle)
考虑使用 Bundle
,而不是使用成对列表。然后你可以用 putExtras(Bundle)
.
添加它
如果你想更进一步,你可以添加一个 lambda 扩展来配置附加功能:
fun <T> Context.openActivity(it: Class<T>, extras: Bundle.() -> Unit = {}) {
val intent = Intent(this, it)
intent.putExtras(Bundle().apply(extras))
startActivity(intent)
}
那么你可以这样称呼它:
openActivity(MyActivity::class.java) {
putString("string.key", "string.value")
putInt("string.key", 43)
...
}
这是开始的扩展函数activity:
inline fun <reified T : Activity> Context.openActivity(noinline extra: Intent.() -> Unit) {
val intent = Intent(this, T::class.java)
intent.extra()
startActivity(intent)
}
你可以这样调用这个函数:
openActivity<MyActivity> {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
putExtra(LaBoxConstants.DEFAULT_LANDING, Default_Landing)
putExtra(HomeActivity.APP_RELAUNCH, AppReLaunched)
}
注意:这不是推荐的开始方式 ACTIVITY。使用 STARTACTIVITY 代替。
声明:
inline fun <reified T : Activity> Context.startActivity(block: Intent.() -> Unit = {}) {
startActivity(Intent(this, T::class.java).apply(block))
}
使用简单:
startActivity<MainActivity>()
有额外的
startActivity<MainActivity>{
putExtra("param 1", "Simple")
}
这是开始的扩展函数activity:
inline fun <reified T : Activity> Context.openActivity(vararg params: Pair<String, Any>) {
val intent = Intent(this, T::class.java)
intent.putExtras(*params)
this.startActivity(intent)
}
fun Intent.putExtras(vararg params: Pair<String, Any>): Intent {
if (params.isEmpty()) return this
params.forEach { (key, value) ->
when (value) {
is Int -> putExtra(key, value)
is Byte -> putExtra(key, value)
is Char -> putExtra(key, value)
is Long -> putExtra(key, value)
is Float -> putExtra(key, value)
is Short -> putExtra(key, value)
is Double -> putExtra(key, value)
is Boolean -> putExtra(key, value)
is Bundle -> putExtra(key, value)
is String -> putExtra(key, value)
is IntArray -> putExtra(key, value)
is ByteArray -> putExtra(key, value)
is CharArray -> putExtra(key, value)
is LongArray -> putExtra(key, value)
is FloatArray -> putExtra(key, value)
is Parcelable -> putExtra(key, value)
is ShortArray -> putExtra(key, value)
is DoubleArray -> putExtra(key, value)
is BooleanArray -> putExtra(key, value)
is CharSequence -> putExtra(key, value)
is Array<*> -> {
when {
value.isArrayOf<String>() ->
putExtra(key, value as Array<String?>)
value.isArrayOf<Parcelable>() ->
putExtra(key, value as Array<Parcelable?>)
value.isArrayOf<CharSequence>() ->
putExtra(key, value as Array<CharSequence?>)
else -> putExtra(key, value)
}
}
is Serializable -> putExtra(key, value)
}
}
return this
}
使用简单:
openActivity<TestActivity>("key0" to "value0", "key1" to "value1")
Kotlin 中提供了一种更简单的方法
Use the bundleOf()
inline fun <reified T : Activity> Context.openActivity1(vararg params: Pair<String, Any?>) {
val intent = Intent(this, T::class.java)
intent.putExtras(bundleOf(*params))
this.startActivity(intent)
}
我个人更喜欢一种方法,我有一个方法为 activity 定义标志,以避免每次调用 startActivity 时都必须重新编写标志。
internal inline fun <reified T: Activity> Context.startActivity(activity: KClass<T>, noinline modifyIntent: Intent.() -> Unit) {
val intent = Intent(this, activity.java)
.addFlags(flagsForActivity(activity))
.modifyIntent()
startActivity(intent)
}
private fun <T: Activity> flagsForActivity(activity: KClass<T>): Int {
return when (activity) {
LoginActivity::class -> Intent.SPECIFIC_FLAGS
else -> Intent.DEFAULT_FLAGS
}
}
然后它的调用方式是
startActivity(LoginActivity::class) {
putExtra("Username", "username")
}
我正在尝试为 Context 编写一个 kotlin 扩展函数,它将在 android 中启动一个新的 activity,并带有给定的 class 名称和意图附加列表。我能够在没有任何额外功能的情况下成功启动 activity,但我遇到了问题。
fun <T> Context.openActivity(it: Class<T>, pairs: List<Pair<String, Any>>) {
var intent = Intent()
pairs.forEach {
intent.putExtra(it.first, it.second)
}
startActivity(intent)
}
Main issue here is -> intent.putExtra() doesn't except second param as Any
Intent
对象中没有方法 putExtra(String, Any)
。您可以使用 Bundle
对象来保存您的数据:
fun <T> Context.openActivity(it: Class<T>, bundleKey: String, bundle: Bundle) {
var intent = Intent(this, it)
intent.putExtra(bundleKey, bundle)
startActivity(intent)
}
要在 Context
对象中调用它:
val bundle = Bundle()
bundle.putString("Key", "Value") // you can put another object here
openActivity(SomeActivity::class.java, "Bundle Key", bundle)
考虑使用 Bundle
,而不是使用成对列表。然后你可以用 putExtras(Bundle)
.
如果你想更进一步,你可以添加一个 lambda 扩展来配置附加功能:
fun <T> Context.openActivity(it: Class<T>, extras: Bundle.() -> Unit = {}) {
val intent = Intent(this, it)
intent.putExtras(Bundle().apply(extras))
startActivity(intent)
}
那么你可以这样称呼它:
openActivity(MyActivity::class.java) {
putString("string.key", "string.value")
putInt("string.key", 43)
...
}
这是开始的扩展函数activity:
inline fun <reified T : Activity> Context.openActivity(noinline extra: Intent.() -> Unit) {
val intent = Intent(this, T::class.java)
intent.extra()
startActivity(intent)
}
你可以这样调用这个函数:
openActivity<MyActivity> {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
putExtra(LaBoxConstants.DEFAULT_LANDING, Default_Landing)
putExtra(HomeActivity.APP_RELAUNCH, AppReLaunched)
}
注意:这不是推荐的开始方式 ACTIVITY。使用 STARTACTIVITY 代替。
声明:
inline fun <reified T : Activity> Context.startActivity(block: Intent.() -> Unit = {}) {
startActivity(Intent(this, T::class.java).apply(block))
}
使用简单:
startActivity<MainActivity>()
有额外的
startActivity<MainActivity>{
putExtra("param 1", "Simple")
}
这是开始的扩展函数activity:
inline fun <reified T : Activity> Context.openActivity(vararg params: Pair<String, Any>) {
val intent = Intent(this, T::class.java)
intent.putExtras(*params)
this.startActivity(intent)
}
fun Intent.putExtras(vararg params: Pair<String, Any>): Intent {
if (params.isEmpty()) return this
params.forEach { (key, value) ->
when (value) {
is Int -> putExtra(key, value)
is Byte -> putExtra(key, value)
is Char -> putExtra(key, value)
is Long -> putExtra(key, value)
is Float -> putExtra(key, value)
is Short -> putExtra(key, value)
is Double -> putExtra(key, value)
is Boolean -> putExtra(key, value)
is Bundle -> putExtra(key, value)
is String -> putExtra(key, value)
is IntArray -> putExtra(key, value)
is ByteArray -> putExtra(key, value)
is CharArray -> putExtra(key, value)
is LongArray -> putExtra(key, value)
is FloatArray -> putExtra(key, value)
is Parcelable -> putExtra(key, value)
is ShortArray -> putExtra(key, value)
is DoubleArray -> putExtra(key, value)
is BooleanArray -> putExtra(key, value)
is CharSequence -> putExtra(key, value)
is Array<*> -> {
when {
value.isArrayOf<String>() ->
putExtra(key, value as Array<String?>)
value.isArrayOf<Parcelable>() ->
putExtra(key, value as Array<Parcelable?>)
value.isArrayOf<CharSequence>() ->
putExtra(key, value as Array<CharSequence?>)
else -> putExtra(key, value)
}
}
is Serializable -> putExtra(key, value)
}
}
return this
}
使用简单:
openActivity<TestActivity>("key0" to "value0", "key1" to "value1")
Kotlin 中提供了一种更简单的方法
Use the bundleOf()
inline fun <reified T : Activity> Context.openActivity1(vararg params: Pair<String, Any?>) {
val intent = Intent(this, T::class.java)
intent.putExtras(bundleOf(*params))
this.startActivity(intent)
}
我个人更喜欢一种方法,我有一个方法为 activity 定义标志,以避免每次调用 startActivity 时都必须重新编写标志。
internal inline fun <reified T: Activity> Context.startActivity(activity: KClass<T>, noinline modifyIntent: Intent.() -> Unit) {
val intent = Intent(this, activity.java)
.addFlags(flagsForActivity(activity))
.modifyIntent()
startActivity(intent)
}
private fun <T: Activity> flagsForActivity(activity: KClass<T>): Int {
return when (activity) {
LoginActivity::class -> Intent.SPECIFIC_FLAGS
else -> Intent.DEFAULT_FLAGS
}
}
然后它的调用方式是
startActivity(LoginActivity::class) {
putExtra("Username", "username")
}