写一个逻辑清晰的startActivityForResult(),拒绝来回扒拉代码
前言
昨天看到郭神公眾號里的一篇文章:使用Fragment優(yōu)雅地處理onActivityResult,調(diào)用的截圖是這樣的
嗯,java語法太長了,我就順便把我之前封裝的Kotlin版貢獻出來吧,寫法巨簡單,如下圖:
怎么樣,是不是簡單多了
ps:更優(yōu)解在這里:以回調(diào)形式使用startActivityForResult方法,并解決Activity被回收的問題_lt的博客-CSDN博客
源碼
import android.app.Activity import android.content.Context import android.content.Intent import android.os.Bundle import android.support.v4.app.Fragment import com.lt.androidkj.utils.extend.ContextConstant/*** 創(chuàng) 建: lt* 保存callback并執(zhí)行startActivityForResult方法的Fragment*/ class ResultCallbackFragment : Fragment() {var mCallback: ((Intent?) -> Unit)? = nullvar intent: Intent? = nullvar result_ok = trueoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)retainInstance = true//當設(shè)備旋轉(zhuǎn)時,fragment會隨托管activity一起銷毀并重建。為true可保留fragment}override fun onAttach(context: Context?) {super.onAttach(context)startActivityForResult(intent, ContextConstant.START_ACTIVITY_FOR_RESULT_REQUEST_CODE)intent = null}override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)activity?.supportFragmentManager?.beginTransaction()?.remove(this)?.commitAllowingStateLoss()if (resultCode == Activity.RESULT_OK && requestCode == ContextConstant.START_ACTIVITY_FOR_RESULT_REQUEST_CODE)mCallback?.invoke(data)else if (!result_ok && requestCode == ContextConstant.START_ACTIVITY_FOR_RESULT_REQUEST_CODE)mCallback?.invoke(data)mCallback = null}fun setCallbackAndIntent(callback: (Intent?) -> Unit, intent: Intent, result_ok: Boolean): ResultCallbackFragment {mCallback = callbackthis.intent = intentthis.result_ok = result_okreturn this} }object ContextConstant {const val START_ACTIVITY_FOR_RESULT_REQUEST_CODE = 965//startActivityForResult方法所使用到的requestCodeconst val TAG = "ResultCallbackFragment"//startActivityForResult方法所使用到的查找fragment用的tag }/*** 使用callback的方式來執(zhí)行startActivityForResult方法,就不用來回查找代碼了,提高了可讀性* 注意事項:會額外耗費一些資源(相當于new一個View)** @param intent 跳轉(zhuǎn)的intent* @param result_ok 是否去判斷result_ok,如果是false,就不判斷* @param callback 成功的回調(diào)*/ fun FragmentActivity.startActivityForResult(intent: Intent, result_ok: Boolean = true, callback: (Intent?) -> Unit) = supportFragmentManager.beginTransaction().add(ResultCallbackFragment().setCallbackAndIntent(callback, intent, result_ok), ContextConstant.TAG).commitAllowingStateLoss()//commit()和該方法的區(qū)別就是,這個方法不會去可以檢查狀態(tài),而commit會檢查狀態(tài)(mStateSaved狀態(tài)),如果狀態(tài)不對則會拋異常fun Fragment.startActivityForResult(intent: Intent, result_ok: Boolean = true, callback: (Intent?) -> Unit) = activity!!.startActivityForResult(intent, result_ok, callback)inline fun <reified A : Activity> FragmentActivity.startActivityForResult(initIntent: (intent: Intent) -> Unit = {}, result_ok: Boolean = true, noinline callback: (Intent?) -> Unit) = startActivityForResult(Intent(this, A::class.java).apply(initIntent), result_ok, callback)inline fun <reified A : Activity> Fragment.startActivityForResult(initIntent: (intent: Intent) -> Unit = {}, result_ok: Boolean = true, noinline callback: (Intent?) -> Unit) = activity!!.startActivityForResult<A>(initIntent, result_ok, callback)直接復制然后粘到一個.kt文件里即可
其實上面這段代碼我是分了三部分寫的,但是為了好復制直接放到一個文件內(nèi)了(也能用,不過我不喜歡大雜燴)
第一部分是一個用來存放回調(diào)和轉(zhuǎn)發(fā)回調(diào)的Fragment
第二部分是一些常量
第三部分就是封裝好的用來調(diào)用的擴展方法
使用
我一共封裝了四個方法,總的來說是兩種,一種直接傳Intent(上面兩個),用來適配隱式意圖,調(diào)用方法如下:
// 裁剪圖片的隱式意圖val intent = Intent("com.android.camera.action.CROP")intent... 中間設(shè)置各種參數(shù)省略startActivityForResult(intent) {如果回調(diào)成功會走這里,it是一個Intent? //也就是可空的Intent}然后下面兩個方法是用來適配顯式意圖的,調(diào)用比上面方便(其實上面也可以調(diào)用顯式意圖)
//直接啟動,不傳多余的參數(shù) startActivityForResult<WebViewActivity> {//回調(diào)位置,it是一個Intent? //也就是可空的Intent }//直接啟動,需要給intent傳參數(shù)的時候 startActivityForResult<WebViewActivity>({//it是一個Intent對象,可以在這里給intent設(shè)置參數(shù)it.putExtra("id",1) }) {//回調(diào)位置,it是一個Intent? //也就是可空的Intent }原理
一句話:通過給Activity添加一個空View的Fragment,然后Activity把startActivityForResult()托管給這個Fragment,回調(diào)成功后通過回調(diào)的方式來簡化邏輯和代碼,從此寫startActivityForResult()就不用來回扒拉代碼了
詳細:首先獲取Fragment,然后通過TAG添加到Activity中,設(shè)置Intent和CallBack,然后在Fragment的onAttach()方法(Fragment和Activity建立連接成功)的時候Fragment調(diào)用startActivityForResult(),然后等onActivityResult()觸發(fā)的時候判斷是否去回調(diào)CallBack,在把自身從Activity中移除,然后完成流程
其實這個并不能說是Activity調(diào)用了startActivityForResult(),而是Activity托管給Fragment來調(diào)用,只是把時機和結(jié)果返回給Activity了
總結(jié)
以上是生活随笔為你收集整理的写一个逻辑清晰的startActivityForResult(),拒绝来回扒拉代码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android的Application的
- 下一篇: 把Spring Boot项目打为可执行j