使用 Fragment 處理 onActivityResult

前言

對Activity和Fragment之間的跳轉(zhuǎn)封裝處理,在Activity/Framgent中用法基本一樣。每個函數(shù)基本上都對應(yīng)著一個擴展函數(shù),方便調(diào)用。

api列表

createIntent            :生成跳轉(zhuǎn)的Intent并添加參數(shù)(可選)
addPair                 :Intent 添加參數(shù)
startActivityK          :跳轉(zhuǎn)
startActivityForResultK :帶回調(diào)的跳轉(zhuǎn)
browse                  :打開瀏覽器
share                   :生調(diào)用分享,只能分享文本
email                   :發(fā)送郵件
makeCallPermission  :撥打電話,需要權(quán)限
makeCall                :撥打電話
sendSMS                 :發(fā)送短信

常規(guī)跳轉(zhuǎn)startActivity,沒有回調(diào)

  1. 不帶任何參數(shù)
IntentKtx.startActivityK(this,TvActivity::class.java)
IntentKtx.startActivityK<TvActivity>(this)
startActivityK<TvActivity>()//擴展函數(shù)
  1. 前兩個是封裝函數(shù),第3個是擴展函數(shù),可以直接在Activity好Fragment中調(diào)用,在其他地方只要有Context也可以調(diào)用擴展函數(shù),方式如下:
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. 對應(yīng)的擴展函數(shù):
  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傳參
//函數(shù)
IntentKtx.startActivityK(this,TvActivity::class.java,"tv" to "one","hai" to "hello")
//擴展函數(shù)
startActivityK(TvActivity::class.java,"tv" to "one","hai" to "hello")
//函數(shù)
IntentKtx.startActivityK<TvActivity>(this,"tv" to "one","hai" to "hello")
//擴展函數(shù)
startActivityK<TvActivity>("tv" to "one","hai" to "hello")

startActivityForResult跳轉(zhuǎn)

使用Fragment處理onActivityResult,網(wǎng)絡(luò)上有很多開源庫都是使用Fragment處理封裝?;卣{(diào)result就是onActivityResult里的resultCode, intent就是回傳的數(shù)據(jù)。

  1. 無參跳轉(zhuǎn)
ActivityHelper.init(this)
    ?.startActivityForResult(TvActivity::class.java){reuslt,intent->
        Log.e(TAG, "btnMainStartListener: $reuslt ---- ${intent?.getStringExtra("key")}");
    }
  1. 對應(yīng)的擴展函數(shù):
startActivityForResultK(TvActivity::class.java){ reuslt ,intent->
            Log.e(TAG, "btnMainStartListener: $reuslt ---- ${intent?.getStringExtra("key")}");
        }
  1. 無參跳轉(zhuǎn),使用內(nèi)聯(lián)函數(shù)
ActivityHelper.init(this)
    ?.startActivityForResult<TvActivity>{reuslt,intent->
        Log.e(TAG, "btnMainStartListener: $reuslt ---- ${intent?.getStringExtra("key")}");
    }
  1. 對應(yīng)的擴展函:
startActivityForResultK<TvActivity>{result ,intent->
      Log.e(TAG, "btnMainStartListener: $result ---${intent?.getStringExtra("key")}")
  }
  1. 使用Intent攜帶參數(shù)跳轉(zhuǎn)
  //帶參數(shù)跳轉(zhuǎn),數(shù)據(jù)放在 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")}")
           }*/
  //擴展函數(shù)
     /* 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帶參跳轉(zhuǎn)
 //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")}")
          }*/
 //擴展函數(shù)
/*      startActivityForResultK(TvActivity::class.java,
          "key" to "key one", "key2" to "key two"){result ,intent->
          Log.e(TAG, "btnMainStartListener: $result ---- ${intent?.getStringExtra("key")}")
      }*/
  1. 使用Pair帶參跳轉(zhuǎn),內(nèi)聯(lián)函數(shù)
//方法一  
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")}")
            }
 //擴展函數(shù)
  startActivityForResultK<TvActivity>("tv" to "key one", "hai" to "key two"){result ,intent->
          Log.e(TAG, "btnMainStartListener: $result ---- ${intent?.getStringExtra("key")}")
      }

在目標(biāo)Activity/Fragment使用

在目標(biāo)Activity/Fragment界面,創(chuàng)建函數(shù)實現(xiàn)跳轉(zhuǎn)。這樣方便其他人調(diào)用跳轉(zhuǎn),而且不用關(guān)心傳值的key,也方便以后同意修改。這里面無法直接使用擴展函數(shù),有些方法雖然可以使用,但是并不比擴展函數(shù)更方便,這里給出示例,按實際情況使用。

companion object{
    //這里使用不了擴展函數(shù),簡單幾個示例,不帶回調(diào)跳轉(zhuǎn)
    //不傳參數(shù)一般也沒必要在這里寫,直接使用擴展函數(shù)更方便
    fun starter(context: Context){
        IntentKtx.startActivityK(context,TvActivity::class.java)
    }
    fun starter2(context: Context){
        IntentKtx.startActivityK<TvActivity>(context)
    }
    //一般這種沒有必要寫在這里,直接用擴展函數(shù)跳轉(zhuǎn)就好了
    fun starter(context: Context,vararg pair: Pair<String,Any?>){
        IntentKtx.startActivityK<TvActivity>(context,*pair)
    }
    //這里比較實現(xiàn)這種情況,key值定好,調(diào)用的地方直接傳對應(yīng)的參數(shù)就行了
    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)
    }
    //帶回調(diào)跳轉(zhuǎn)
    fun starter(context: Context?,callback: ((Int, Intent?) -> Unit)?){
        ActivityHelper.init(context)
            ?.startActivityForResult<TvActivity>(callback)
    }
    //回調(diào)也一樣,這里比較適合這種情況
    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)
        }
        //或者寫成這樣,實現(xiàn)方式有很多,可以自由組合
        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)
        }
}

其他界面調(diào)用示例:

        //調(diào)用跳轉(zhuǎn)類的跳轉(zhuǎn)方法
//        TvActivity.starter(this)
//        TvActivity.starter(this,"one","two")
        //回調(diào)跳轉(zhuǎn)
//        TvActivity.starter(this,"one","two"){result,intent ->
//            Log.e(TAG, "btnMainStartListener: $result ---- ${intent?.getStringExtra("key")}")
//        }

源碼

內(nèi)容比較簡單,只有三個類,約400行代碼。復(fù)制到代碼中即可使用。

  • 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)
        //防止重復(fù)創(chuàng)建
        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)
        //處理返回的結(jié)果
        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}")
            }
        }
    }

    /**
     * 不帶回調(diào)跳轉(zhuǎn)相關(guān)
     */
    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) }
}

/**
 * 不帶回調(diào),無參跳轉(zhuǎn)
 */
fun Context?.startActivityK(clazz: Class<*>) {
    this?.startActivity(Intent(this, clazz))
}

inline fun <reified T> Context?.startActivityK() {
    this?.startActivity(Intent(this, T::class.java))
}

/**
 * 不帶回調(diào),帶參跳轉(zhuǎn)
 */
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))
    }
}

/**
 * 不帶回調(diào),無參跳轉(zhuǎn)
 */
fun Fragment?.startActivityK(clazz: Class<*>) {
    this?.startActivity(Intent(activity, clazz))
}

inline fun <reified T> Fragment?.startActivityK() {
    this?.startActivity(Intent(activity, T::class.java))
}

/**
 * 不帶回調(diào),帶參跳轉(zhuǎn)
 */
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擴展函數(shù)跳轉(zhuǎn)
 */
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) {
            //創(chuàng)建 fragment,加入當(dāng)前 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跳轉(zhuǎn),不帶參數(shù)
     */
    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)
        }
    }

    /**
     *帶參數(shù)跳轉(zhuǎn)
     * @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跳轉(zhuǎn),帶參數(shù)
     * @param intent  參數(shù)提取放入intent中
     * @param callback
     */
    fun startActivityForResult(intent: Intent, callback: ((Int, Intent?) -> Unit)?) {
        mRouterFragment?.run {
            startActivityForResult(intent, callback)
        }
    }


}

導(dǎo)入依賴

不想復(fù)制更省事的方法,直接依賴即可。依賴如下:
Github上面有詳細(xì)的文檔。
最新版

    allprojects {
        repositories {
            ...
            maven { url 'https://www.jitpack.io' }
        }
    }

dependencies {
            implementation 'com.github.KiWiLss:LUtils:1.1.0'
    }

使用前要調(diào)用,獲取到 Context:

object LUtilsConfig{

    lateinit var mContext: Context
    fun init(context: Context) {
        mContext = context
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容