前言
对Activity和Fragment之间的跳转封装处理,在Activity/Framgent中用法基本一样。每个函数基本上都对应着一个扩展函数,方便调用。实现方式有很多种,可以自由组合,实际使用时按需求使用。
Intent 扩展函数api列表
//传值解析函数intentK :intent 获取传值扩展函数//创建 intentintentOf :生成Intent并添加参数(可选)createIntent :生成Intent并添加参数(可选)createActivityIntent:生成跳转的Intent并添加参数,也可以不添加参数createBroadcastIntent:生成发送广播 intent,可以添加参数addPair :Intent 添加参数startActivityK :跳转startActivityForResultK :带回调的跳转browse :打开浏览器share :生调用分享,只能分享文本email :发送邮件makeCallPermission :拨打电话,需要权限makeCall :拨打电话sendSMS :发送短信
常规跳转startActivity,没有回调
不带任何参数
IntentKtx.startActivityK(this,TvActivity::class.java)IntentKtx.startActivityK<TvActivity>(this)startActivityK<TvActivity>()//扩展函数
前两个是封装函数,第3个是扩展函数,可以直接在Activity好Fragment中调用,在其他地方只要有Context也可以调用扩展函数,方式如下:
context.startActivityK<TvActivity>()
使用Intent传参
val intent = Intent(this,TvActivity::class.java)intent.putExtra("tv","one")intent.putExtra("hai","hai---")IntentKtx.startActivityK(this,intent)
对应的扩展函数:
val intent = Intent(this,TvActivity::class.java)intent.putExtra("tv","one")intent.putExtra("hai","hai---")// IntentKtx.startActivityK(this,intent)startActivityK(intent)
更简便的写法: ``` Intent(this,TvActivity::class.java) .addPair(“tv” to “one”, “hai” to “two”) ?.let { startActivityK(it) }
//或者
createIntent
3. 使用Pair传参
//函数 IntentKtx.startActivityK(this,TvActivity::class.java,”tv” to “one”,”hai” to “hello”) //扩展函数 startActivityK(TvActivity::class.java,”tv” to “one”,”hai” to “hello”)
```//函数IntentKtx.startActivityK<TvActivity>(this,"tv" to "one","hai" to "hello")//扩展函数startActivityK<TvActivity>("tv" to "one","hai" to "hello")
startActivityForResult跳转
使用Fragment处理onActivityResult,网络上有很多开源库都是使用Fragment处理封装。回调result就是onActivityResult里的resultCode, intent就是回传的数据。
无参跳转
ActivityHelper.init(this)?.startActivityForResult(TvActivity::class.java){reuslt,intent->Log.e(TAG, "btnMainStartListener: $reuslt ---- ${intent?.getStringExtra("key")}");}
对应的扩展函数:
startActivityForResultK(TvActivity::class.java){ reuslt ,intent->Log.e(TAG, "btnMainStartListener: $reuslt ---- ${intent?.getStringExtra("key")}");}
无参跳转,使用内联函数
ActivityHelper.init(this)?.startActivityForResult<TvActivity>{reuslt,intent->Log.e(TAG, "btnMainStartListener: $reuslt ---- ${intent?.getStringExtra("key")}");}
对应的扩展函:
startActivityForResultK<TvActivity>{result ,intent->Log.e(TAG, "btnMainStartListener: $result ---${intent?.getStringExtra("key")}")}
使用Intent携带参数跳转
//带参数跳转,数据放在 intent 里面/* val intent2 = Intent(this,TvActivity::class.java)intent2.putExtra("tv","key one")ActivityHelper.init(this)?.startActivityForResult(intent2){result ,intent->Log.e(TAG, "btnMainStartListener: $result ---- ${intent?.getStringExtra("key")}")}*///扩展函数/* val intent2 = Intent(this,TvActivity::class.java)intent2.putExtra("tv","key one")startActivityForResultK(intent2){result ,intent->Log.e(TAG, "btnMainStartListener: $result ---- ${intent?.getStringExtra("key")}")}*/
使用Pair带参跳转
//pair 传值/*ActivityHelper.init(this)?.startActivityForResult(TvActivity::class.java,"tv" to "key one", "hai" to "key two"){result ,intent->Log.e(TAG, "btnMainStartListener: $result ---- ${intent?.getStringExtra("key")}")}*///扩展函数/* startActivityForResultK(TvActivity::class.java,"key" to "key one", "key2" to "key two"){result ,intent->Log.e(TAG, "btnMainStartListener: $result ---- ${intent?.getStringExtra("key")}")}*/
使用Pair带参跳转,内联函数
//方法一ActivityHelper.init(this)?.startActivityForResult(TvActivity::class.java,{result ,intent->Log.e(TAG, "btnMainStartListener: $result ---- ${intent?.getStringExtra("key")}")},"key" to "key one", "key2" to "key two")//方法二ActivityHelper.init(this)?.startActivityForResult<TvActivity>("key" to "key one", "key2" to "key two"){result ,intent->Log.e(TAG, "btnMainStartListener: $result ---- ${intent?.getStringExtra("key")}")}//扩展函数startActivityForResultK<TvActivity>("tv" to "key one", "hai" to "key two"){result ,intent->Log.e(TAG, "btnMainStartListener: $result ---- ${intent?.getStringExtra("key")}")}
在目标Activity/Fragment使用
在目标Activity/Fragment界面,创建函数实现跳转。这样方便其他人调用跳转,而且不用关心传值的key,也方便以后同意修改。这里面无法直接使用扩展函数,有些方法虽然可以使用,但是并不比扩展函数更方便,这里给出几个简单示例,实现方式有很多种,可以自由组合,实际使用时按需求使用。
companion object{//这里不能直接使用扩展函数,简单几个示例,不带回调跳转//不传参数一般也没必要在这里写,直接使用扩展函数更方便fun starter(context: Context){IntentKtx.startActivityK(context,TvActivity::class.java)}fun starter2(context: Context){IntentKtx.startActivityK<TvActivity>(context)}//一般这种没有必要写在这里,直接用扩展函数跳转就好了fun starter(context: Context,vararg pair: Pair<String,Any?>){IntentKtx.startActivityK<TvActivity>(context,*pair)}//这里比较实现这种情况,key值定好,调用的地方直接传对应的参数就行了fun starter(context: Context,tv: String?,hai: String?){val intent = Intent(context,TvActivity::class.java)intent.addPair("tv" to tv, "hai" to hai)IntentKtx.startActivityK(context,intent)}//带回调跳转fun starter(context: Context?,callback: ((Int, Intent?) -> Unit)?){ActivityHelper.init(context)?.startActivityForResult<TvActivity>(callback)}//回调也一样,这里比较适合这种情况fun starter(context: Context?,tv: String?,hai: String?,callback: ((Int, Intent?) -> Unit)?){val intent = Intent(context,TvActivity::class.java)intent.addPair("tv" to tv, "hai" to hai)ActivityHelper.init(context)?.startActivityForResult(intent,callback)}//写成下面这样更fun starter(context: Context, tv: String?, hai: String?, callback: ((Int, Intent?) -> Unit)?){val intent = context.createIntent<TextViewActivity>("tv" to tv, "hai" to hai)ActivityHelper.init(context)?.startActivityForResult(intent,callback)}//或者写成这样,实现方式有很多,可以自由组合fun starter2(context: Context, tv: String?, hai: String?, callback: ((Int, Intent?) -> Unit)?){val intent = context.createIntent<TextViewActivity>("tv" to tv, "hai" to hai)context.startActivityForResultK(intent,callback)}}
其他界面调用示例:
//调用跳转类的跳转方法// TvActivity.starter(this)// TvActivity.starter(this,"one","two")//回调跳转// TvActivity.starter(this,"one","two"){result,intent ->// Log.e(TAG, "btnMainStartListener: $result ---- ${intent?.getStringExtra("key")}")// }
源码
内容比较简单,只有三个类,约400行代码。复制到代码中即可使用。
RouterFragment ```kotlin class RouterFragment : Fragment() {
private val mCallbacks: SparseArray<((Int, Intent?) -> Unit)?> = SparseArray()
private val mCodeGenerator: Random = Random()
companion object {
fun newInstance(): RouterFragment? {return RouterFragment()}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)//防止重复创建retainInstance = true
}
fun startActivityForResult(intent: Intent, callback: ((Int, Intent?) -> Unit)?) {
val requestCode = makeRequestCode()mCallbacks.put(requestCode, callback)startActivityForResult(intent, requestCode)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)//处理返回的结果val callback = mCallbacks[requestCode]mCallbacks.remove(requestCode)callback?.run {invoke(resultCode, data)}
}
/**
- 随机生成唯一的requestCode,最多尝试10次
- @return
*/
private fun makeRequestCode(): Int {
var requestCode: Int
var tryCount = 0
do {
} while (mCallbacks.indexOfKey(requestCode) >= 0 && tryCount < 10) return requestCode }requestCode = mCodeGenerator.nextInt(0x0000FFFF)tryCount++
}
- IntentKtx```kotlinobject IntentKtx {fun addPair(intent: Intent, vararg params: Pair<String, Any?>) {params.forEach {when (val value = it.second) {null -> intent.putExtra(it.first, null as Serializable?)is Int -> intent.putExtra(it.first, value)is Long -> intent.putExtra(it.first, value)is CharSequence -> intent.putExtra(it.first, value)is String -> intent.putExtra(it.first, value)is Float -> intent.putExtra(it.first, value)is Double -> intent.putExtra(it.first, value)is Char -> intent.putExtra(it.first, value)is Short -> intent.putExtra(it.first, value)is Boolean -> intent.putExtra(it.first, value)is Serializable -> intent.putExtra(it.first, value)is Bundle -> intent.putExtra(it.first, value)is Parcelable -> intent.putExtra(it.first, value)is Array<*> -> when {value.isArrayOf<CharSequence>() -> intent.putExtra(it.first, value)value.isArrayOf<String>() -> intent.putExtra(it.first, value)value.isArrayOf<Parcelable>() -> intent.putExtra(it.first, value)else -> throw Exception("Intent extra ${it.first} has wrong type ${value.javaClass.name}")}is IntArray -> intent.putExtra(it.first, value)is LongArray -> intent.putExtra(it.first, value)is FloatArray -> intent.putExtra(it.first, value)is DoubleArray -> intent.putExtra(it.first, value)is CharArray -> intent.putExtra(it.first, value)is ShortArray -> intent.putExtra(it.first, value)is BooleanArray -> intent.putExtra(it.first, value)else -> throw Exception("Intent extra ${it.first} has wrong type ${value.javaClass.name}")}}}/*** 不带回调跳转相关*/fun startActivityK(context: Context?, clazz: Class<*>) {context?.startActivity(Intent(context, clazz))}inline fun <reified T> startActivityK(context: Context?) {context?.startActivity(Intent(context, T::class.java))}fun startActivityK(context: Context?, intent: Intent) {context?.startActivity(intent)}fun startActivityK(context: Context?, clazz: Class<*>, vararg params: Pair<String, Any?>) {context?.run {val intent = Intent(this, clazz)intent.addPair(*params)startActivity(intent)}}inline fun <reified T> startActivityK(context: Context?, vararg params: Pair<String, Any?>) {context?.run {val intent = Intent(this, T::class.java)intent.addPair(*params)startActivity(intent)}}}/***生成跳转的Intent并添加参数* @param T* @param pair*/inline fun <reified T> Context.createIntentStart(vararg pair: Pair<String, Any?>) =Intent(this, T::class.java).apply {addPair(*pair)}/***生成Intent添加参数,也可以不添加*/fun Context.createIntent(vararg pair: Pair<String, Any?>) = Intent().addPair(*pair)/***给Intent添加参数* @param params* @return*/fun Intent?.addPair(vararg params: Pair<String, Any?>): Intent? {return this?.also { IntentKtx.addPair(it, *params) }}/*** 不带回调,无参跳转*/fun Context?.startActivityK(clazz: Class<*>) {this?.startActivity(Intent(this, clazz))}inline fun <reified T> Context?.startActivityK() {this?.startActivity(Intent(this, T::class.java))}/*** 不带回调,带参跳转*/fun Context?.startActivityK(intent: Intent) {this?.startActivity(intent)}fun Context?.startActivityK(clazz: Class<*>, vararg pair: Pair<String, Any?>) {this?.run {val intent = Intent(this, clazz)startActivity(intent.addPair(*pair))}}inline fun <reified T> Context?.startActivityK(vararg pair: Pair<String, Any?>) {this?.run {val intent = Intent(this, T::class.java)startActivity(intent.addPair(*pair))}}/*** 不带回调,无参跳转*/fun Fragment?.startActivityK(clazz: Class<*>) {this?.startActivity(Intent(activity, clazz))}inline fun <reified T> Fragment?.startActivityK() {this?.startActivity(Intent(activity, T::class.java))}/*** 不带回调,带参跳转*/fun Fragment?.startActivityK(intent: Intent) {this?.startActivity(intent)}fun Fragment?.startActivityK(clazz: Class<*>, vararg pair: Pair<String, Any?>) {this?.run {val intent = Intent(activity, clazz)startActivity(intent.addPair(*pair))}}inline fun <reified T> Fragment?.startActivityK(vararg pair: Pair<String, Any?>) {this?.run {val intent = Intent(activity, T::class.java)startActivity(intent.addPair(*pair))}}/*** Context扩展函数跳转*/fun Context?.startActivityForResultK(clazz: Class<*>, callback: ((Int, Intent?) -> Unit)?) {ActivityHelper.init(this)?.startActivityForResult(clazz, callback)}fun Context?.startActivityForResultK(intent: Intent, callback: ((Int, Intent?) -> Unit)?) {ActivityHelper.init(this)?.startActivityForResult(intent, callback)}inline fun <reified T> Context?.startActivityForResultK(noinline callback: ((Int, Intent?) -> Unit)?) {ActivityHelper.init(this)?.startActivityForResult<T>(callback)}fun Context?.startActivityForResultK(clazz: Class<*>,vararg pair: Pair<String, Any?>,callback: ((Int, Intent?) -> Unit)?) {ActivityHelper.init(this)?.startActivityForResult(clazz, callback, *pair)}inline fun <reified T> Context?.startActivityForResultK(vararg pair: Pair<String, Any?>,noinline callback: ((Int, Intent?) -> Unit)?) {ActivityHelper.init(this)?.startActivityForResult<T>(callback, *pair)}/*** 上述方法在 fragment 中扩展*/fun Fragment?.startActivityForResultK(clazz: Class<*>, callback: ((Int, Intent?) -> Unit)?) {ActivityHelper.init(this?.context)?.startActivityForResult(clazz, callback)}fun Fragment?.startActivityForResultK(intent: Intent, callback: ((Int, Intent?) -> Unit)?) {ActivityHelper.init(this?.context)?.startActivityForResult(intent, callback)}inline fun <reified T> Fragment?.startActivityForResultK(noinline callback: ((Int, Intent?) -> Unit)?) {ActivityHelper.init(this?.context)?.startActivityForResult<T>(callback)}fun Fragment?.startActivityForResultK(clazz: Class<*>,vararg pair: Pair<String, Any?>,callback: ((Int, Intent?) -> Unit)?) {ActivityHelper.init(this?.context)?.startActivityForResult(clazz, callback, *pair)}inline fun <reified T> Fragment?.startActivityForResultK(vararg pair: Pair<String, Any?>,noinline callback: ((Int, Intent?) -> Unit)?) {ActivityHelper.init(this?.context)?.startActivityForResult<T>(callback, *pair)}/***跳转到浏览器* @param url* @param newTask* @return*/fun Context.browse(url: String, newTask: Boolean = false): Boolean {return try {val intent = Intent(Intent.ACTION_VIEW)intent.data = Uri.parse(url)if (newTask) {intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)}startActivity(intent)true} catch (e: ActivityNotFoundException) {e.printStackTrace()false}}/***跳转到浏览器* @param url* @param newTask* @return*/fun Fragment.browse(url: String, newTask: Boolean = false) = activity?.browse(url, newTask)/***原生调用分享,只能分享文本* @param text* @param subject* @param title* @return*/fun Context.share(text: String, subject: String = "", title: String? = null): Boolean {return try {val intent = Intent(android.content.Intent.ACTION_SEND)intent.type = "text/plain"intent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject)intent.putExtra(android.content.Intent.EXTRA_TEXT, text)startActivity(Intent.createChooser(intent, title))true} catch (e: ActivityNotFoundException) {e.printStackTrace()false}}/***发送邮件* @param email* @param subject* @param text* @return*/@SuppressLint("QueryPermissionsNeeded")fun Context.email(email: String, subject: String = "", text: String = ""): Boolean {val intent = Intent(Intent.ACTION_SENDTO)intent.data = Uri.parse("mailto:")intent.putExtra(Intent.EXTRA_EMAIL, arrayOf(email))if (subject.isNotEmpty())intent.putExtra(Intent.EXTRA_SUBJECT, subject)if (text.isNotEmpty())intent.putExtra(Intent.EXTRA_TEXT, text)if (intent.resolveActivity(packageManager) != null) {startActivity(intent)return true}return false}/***拨打电话,需要权限permission.CALL_PHONE才能拨打* @param number* @return*/@SuppressLint("MissingPermission")fun Context.makeCallPermission(number: String): Boolean {return try {val intent = Intent(Intent.ACTION_CALL, Uri.parse("tel:$number"))startActivity(intent)true} catch (e: Exception) {e.printStackTrace()false}}fun Fragment.markCallPermission(number: String) = context?.makeCallPermission(number)/***拨打电话,不需要权限,跳转到拨打电话界面* @param number* @return*/fun Context.makeCall(number: String) {val uri = Uri.parse("tel:$number")val it = Intent(Intent.ACTION_DIAL, uri)startActivity(it)}fun Fragment.markCall(number: String) = context?.makeCall(number)/***发送短信* @param number* @param text* @return*/fun Context.sendSMS(number: String, text: String = ""): Boolean {return try {val intent = Intent(Intent.ACTION_VIEW, Uri.parse("sms:$number"))intent.putExtra("sms_body", text)startActivity(intent)true} catch (e: Exception) {e.printStackTrace()false}}fun Fragment.sendSMS(number: String, text: String = "") = context
ActivityHelper ```kotlin class ActivityHelper private constructor(activity: FragmentActivity) { private val TAG = “MMMK” var mContext: Activity? = null private var mRouterFragment: RouterFragment? = null
init {
mContext = activitymRouterFragment = getRouterFragment(activity)
}
companion object { // fun init(activity: FragmentActivity?): ActivityHelper? { // if (activity != null) return ActivityHelper(activity) // return null // }
fun init(context: Context?): ActivityHelper? {if (context is FragmentActivity) return ActivityHelper(context)return null}
}
private fun getRouterFragment(activity: FragmentActivity): RouterFragment? {var routerFragment: RouterFragment? = findRouterFragment(activity)if (routerFragment == null) {//创建 fragment,加入当前 activityrouterFragment = RouterFragment.newInstance()val sfm = activity.supportFragmentManagersfm.beginTransaction().add(routerFragment!!, TAG).commitAllowingStateLoss()sfm.executePendingTransactions()}return routerFragment}private fun findRouterFragment(activity: FragmentActivity): RouterFragment? {//通过 tag 获取 fragmentreturn activity.supportFragmentManager.findFragmentByTag(TAG) as RouterFragment?}/*** 对Intent跳转,不带参数*/fun startActivityForResult(clazz: Class<*>,callback: ((Int, Intent?) -> Unit)?) {mContext?.run {val intent = Intent(this, clazz)startActivityForResult(intent, callback)}}inline fun <reified T> startActivityForResult(noinline callback: ((Int, Intent?) -> Unit)?) {mContext?.run {val intent = Intent(mContext, T::class.java)startActivityForResult(intent, callback)}}/***带参数跳转* @param T* @param pair* @param callback*/inline fun <reified T> startActivityForResult(vararg pair: Pair<String, Any?>,noinline callback: ((Int, Intent?) -> Unit)?) {if (mContext == null) returnval intent = Intent(mContext, T::class.java)IntentKtx.addPair(intent, *pair)startActivityForResult(intent, callback)}inline fun <reified T> startActivityForResult(noinline callback: ((Int, Intent?) -> Unit)?,vararg pair: Pair<String, Any?>) {if (mContext == null) returnval intent = Intent(mContext, T::class.java)IntentKtx.addPair(intent, *pair)startActivityForResult(intent, callback)}fun startActivityForResult(clazz: Class<*>,vararg pair: Pair<String, Any?>,callback: ((Int, Intent?) -> Unit)?) {mContext?.run {val intent = Intent(this, clazz)IntentKtx.addPair(intent, *pair)startActivityForResult(intent, callback)}}fun startActivityForResult(clazz: Class<*>,callback: ((Int, Intent?) -> Unit)?,vararg pair: Pair<String, Any?>) {mContext?.run {val intent = Intent(this, clazz)IntentKtx.addPair(intent, *pair)startActivityForResult(intent, callback)}}/*** 对Intent跳转,带参数* @param intent 参数提取放入intent中* @param callback*/fun startActivityForResult(intent: Intent, callback: ((Int, Intent?) -> Unit)?) {mRouterFragment?.run {startActivityForResult(intent, callback)}}
}
<a name="Sr423"></a>## 导入依赖不想复制更省事的方法,直接依赖即可。依赖如下:<br />[Github](https://github.com/KiWiLss/LUtils)上面有详细的文档。<br />[最新版](https://www.jitpack.io/v/KiWiLss/LUtils.svg)```kotlinallprojects {repositories {...maven { url 'https://www.jitpack.io' }}}dependencies {implementation 'com.github.KiWiLss:LUtils:1.1.0'}
使用前要调用,获取到 Context:
object LUtilsConfig{lateinit var mContext: Contextfun init(context: Context) {mContext = context}
