美文网首页
使用 Fragment 处理 onActivityResult

使用 Fragment 处理 onActivityResult

作者: FlyClound | 来源:发表于2021-06-26 00:04 被阅读0次

    前言

    对Activity和Fragment之间的跳转封装处理,在Activity/Framgent中用法基本一样。每个函数基本上都对应着一个扩展函数,方便调用。

    api列表

    createIntent            :生成跳转的Intent并添加参数(可选)
    addPair                 :Intent 添加参数
    startActivityK          :跳转
    startActivityForResultK :带回调的跳转
    browse                  :打开浏览器
    share                   :生调用分享,只能分享文本
    email                   :发送邮件
    makeCallPermission  :拨打电话,需要权限
    makeCall                :拨打电话
    sendSMS                 :发送短信
    

    常规跳转startActivity,没有回调

    1. 不带任何参数
    IntentKtx.startActivityK(this,TvActivity::class.java)
    IntentKtx.startActivityK<TvActivity>(this)
    startActivityK<TvActivity>()//扩展函数
    
    1. 前两个是封装函数,第3个是扩展函数,可以直接在Activity好Fragment中调用,在其他地方只要有Context也可以调用扩展函数,方式如下:
    context.startActivityK<TvActivity>()
    
    1. 使用Intent传参
     val intent = Intent(this,TvActivity::class.java)
     intent.putExtra("tv","one")
     intent.putExtra("hai","hai---")
     IntentKtx.startActivityK(this,intent)
    
    1. 对应的扩展函数:
      val intent = Intent(this,TvActivity::class.java)
            intent.putExtra("tv","one")
            intent.putExtra("hai","hai---")
    //        IntentKtx.startActivityK(this,intent)
            startActivityK(intent)
    
    1. 更简便的写法:
    Intent(this,TvActivity::class.java)
        .addPair("tv" to "one", "hai" to "two")
        ?.let { startActivityK(it) }
    
    1. 使用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就是回传的数据。

    1. 无参跳转
    ActivityHelper.init(this)
        ?.startActivityForResult(TvActivity::class.java){reuslt,intent->
            Log.e(TAG, "btnMainStartListener: $reuslt ---- ${intent?.getStringExtra("key")}");
        }
    
    1. 对应的扩展函数:
    startActivityForResultK(TvActivity::class.java){ reuslt ,intent->
                Log.e(TAG, "btnMainStartListener: $reuslt ---- ${intent?.getStringExtra("key")}");
            }
    
    1. 无参跳转,使用内联函数
    ActivityHelper.init(this)
        ?.startActivityForResult<TvActivity>{reuslt,intent->
            Log.e(TAG, "btnMainStartListener: $reuslt ---- ${intent?.getStringExtra("key")}");
        }
    
    1. 对应的扩展函:
    startActivityForResultK<TvActivity>{result ,intent->
          Log.e(TAG, "btnMainStartListener: $result ---${intent?.getStringExtra("key")}")
      }
    
    1. 使用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")}")
          }*/
    
    1. 使用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")}")
          }*/
    
    1. 使用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
    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 {
                requestCode = mCodeGenerator.nextInt(0x0000FFFF)
                tryCount++
            } while (mCallbacks.indexOfKey(requestCode) >= 0 && tryCount < 10)
            return requestCode
        }
    
    
    }
    
    • IntentKtx
    object 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)
            }
        }
    }
    
    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)
    }
    
    • ActivityHelper
    class ActivityHelper private constructor(activity: FragmentActivity) {
        private val TAG = "MMMK"
        var mContext: Activity? = null
        private var mRouterFragment: RouterFragment? = null
    
        init {
            mContext = activity
            mRouterFragment = 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,加入当前 activity
                routerFragment = RouterFragment.newInstance()
                val sfm = activity.supportFragmentManager
                sfm.beginTransaction().add(routerFragment!!, TAG).commitAllowingStateLoss()
                sfm.executePendingTransactions()
            }
            return routerFragment
        }
    
        private fun findRouterFragment(activity: FragmentActivity): RouterFragment? {
            //通过 tag 获取 fragment
            return 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) return
            val 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) return
            val 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)
            }
        }
    
    
    }
    

    导入依赖

    不想复制更省事的方法,直接依赖即可。依赖如下:
    Github上面有详细的文档。
    最新版

        allprojects {
            repositories {
                ...
                maven { url 'https://www.jitpack.io' }
            }
        }
    
    dependencies {
                implementation 'com.github.KiWiLss:LUtils:1.1.0'
        }
    
    

    使用前要调用,获取到 Context:

    object LUtilsConfig{
    
        lateinit var mContext: Context
        fun init(context: Context) {
            mContext = context
        }
    

    相关文章

      网友评论

          本文标题:使用 Fragment 处理 onActivityResult

          本文链接:https://www.haomeiwen.com/subject/yuyayltx.html