在項(xiàng)目開發(fā)過程中碧查,如果有用戶系統(tǒng)少不了登錄狀態(tài)的判斷,通常的一種實(shí)現(xiàn)方式是在baseActivity中獲取登陸狀態(tài)绿贞,當(dāng)需要時(shí)進(jìn)行if else判斷脂男,這樣每次需要時(shí)就進(jìn)行判斷一次非常的麻煩,現(xiàn)在我們可以用kotlin的擴(kuò)展函數(shù)功能實(shí)現(xiàn)統(tǒng)一的登錄判斷及登錄后的自動(dòng)跳轉(zhuǎn)。
首先說一下什么是擴(kuò)展函數(shù),簡(jiǎn)單來(lái)說,擴(kuò)展函數(shù)就是讓一個(gè)已存在的類實(shí)現(xiàn)一些我們自定義的功能部翘,如果我們對(duì)一個(gè)父類實(shí)現(xiàn)了擴(kuò)展函數(shù),那么它的子類也會(huì)具有擴(kuò)展功能响委,首先舉個(gè)例子:
fun View.slideExit() {
if (translationY == 0f) animate().setInterpolator(AccelerateInterpolator()).setDuration(default_duration_short).translationY(height.toFloat())
}
我們?cè)谶@里給View增加了一個(gè)滑動(dòng)退出功能新思,那么所有集成View的類都具有了這個(gè)功能,比如TextView赘风,我們可以直接調(diào)用
var tx=TextView(this)
tx.slideExit()
下面來(lái)說所如何完成統(tǒng)一的登錄狀態(tài)判斷以及登錄后的自動(dòng)跳轉(zhuǎn)夹囚,通常我們的界面容器都是activit或者fragment,所以我們就給這兩個(gè)類增加一個(gè)擴(kuò)展函數(shù)功能邀窃,由于代碼是一樣的
這里就那Activity舉例荸哟,代碼如下
inline fun <reified T : Activity> Activity.checkLoginToStart(vararg params: Pair<String, Any>) {
var isLogin = AccountTool.isLogined(this)
if (isLogin) {
AnkoInternals.internalStartActivity(this, T::class.java, params)
} else {
var i = AnkoInternals.createIntent(this, T::class.java, params)
i.putExtra(LoginActivity.TARGET, "${T::class.java.`package`}.${T::class.java.simpleName}")
i.setClass(this, LoginActivity::class.java)
startActivity(i)
}
}
注意擴(kuò)展函數(shù)的寫法 是Activity.checkLoginToStart,如果是Fragment就是Fragment.checkLoginToStart
在這個(gè)函數(shù)需要一個(gè)Pair<String,Any>類型參數(shù)瞬捕,用于傳遞參數(shù)鞍历,這是一個(gè)可選的,在函數(shù)內(nèi)部先獲取了一下登陸狀態(tài)肪虎,如果是已登錄直接啟動(dòng)目標(biāo)Activity劣砍,如果是未登錄那么我們先通過AnkoInternals.createIntent把參數(shù)封裝起來(lái),但是此時(shí)指定的activity是目標(biāo)Activity即T::class.java扇救,而我們想要到達(dá)的是LoginActivity刑枝,所以通過setClass重新指定Activity,同時(shí)我們把目標(biāo)activity的絕對(duì)路徑也傳遞給LoginActivity迅腔,用于登錄后的自動(dòng)跳轉(zhuǎn)装畅。這樣我們就成功跳轉(zhuǎn)到了LoginActivity,并且攜帶了目標(biāo)activity的啟動(dòng)參數(shù)沧烈。
在LoginActivity中假如我們正確輸入了用戶名和密碼掠兄,成功登陸了,那么在成功后的接口中我們進(jìn)行這樣的處理
onsuccess{
var i = intent
var target = i.getStringExtra(TARGET)
if (target.isNullOrEmpty()) {
finish()
} else {
var reTarget = if (target.contains("package")) target.replace("package", "").trim() else target.trim()
i.setClassName(this@LoginActivity, reTarget)
i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
startActivity(i)
finish()
}
}
比如onSuccess方法是我們登錄成功后的回調(diào)方法掺出,首先我們獲取目標(biāo)Activity的絕對(duì)路徑徽千,這里進(jìn)行了一次判斷苫费,如果我們是直接啟動(dòng)的登錄界面是沒有目標(biāo)Activity的汤锨,所以直接finish,如果有那么通過setClassName設(shè)置啟動(dòng)的目標(biāo)activity后直接通過這個(gè)intent啟動(dòng)百框,注意此時(shí)這個(gè)intent中還攜帶了我們目標(biāo)activity中需要的參數(shù)闲礼,這樣登錄成功后就成功跳轉(zhuǎn)到了目標(biāo)activity,參數(shù)也正常的傳遞了。到此整個(gè)流程分析完畢柬泽。
最后當(dāng)我們?cè)赼ctivit中使用時(shí)慎菲,直接在Activit中調(diào)用
checkLoginToStart<UserCenterActivity>()
如果你需要給Activity傳遞參數(shù) 則
checkLoginToStart<UserCenterActivity>(KEY to VALUE)
這樣一來(lái)少了一層邏輯判斷,代碼可讀性也更高锨并。