Kotlin-優雅的完成登入判斷及自動跳轉功能

Knight_Davion發表於2017-07-06

在專案開發過程中,如果有使用者系統少不了登入狀態的判斷,通常的一種實現方式是在baseActivity中獲取登陸狀態,當需要時進行if else判斷,這樣每次需要時就進行判斷一次非常的麻煩,現在我們可以用kotlin的擴充套件函式功能實現統一的登入判斷及登入後的自動跳轉。
首先說一下什麼是擴充套件函式,簡單來說,擴充套件函式就是讓一個已存在的類實現一些我們自定義的功能,如果我們對一個父類實現了擴充套件函式,那麼它的子類也會具有擴充套件功能,首先舉個例子:

fun View.slideExit() {
    if (translationY == 0f) animate().setInterpolator(AccelerateInterpolator()).setDuration(default_duration_short).translationY(height.toFloat())
}複製程式碼

我們在這裡給View增加了一個滑動退出功能,那麼所有整合View的類都具有了這個功能,比如TextView,我們可以直接呼叫

var tx=TextView(this)
tx.slideExit()複製程式碼

下面來說所如何完成統一的登入狀態判斷以及登入後的自動跳轉,通常我們的介面容器都是activit或者fragment,所以我們就給這兩個類增加一個擴充套件函式功能,由於程式碼是一樣的
這裡就那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)
    }
}複製程式碼

注意擴充套件函式的寫法 是Activity.checkLoginToStart,如果是Fragment就是Fragment.checkLoginToStart
在這個函式需要一個Pair<String,Any>型別引數,用於傳遞引數,這是一個可選的,在函式內部先獲取了一下登陸狀態,如果是已登入直接啟動目標Activity,如果是未登入那麼我們先通過AnkoInternals.createIntent把引數封裝起來,但是此時指定的activity是目標Activity即T::class.java,而我們想要到達的是LoginActivity,所以通過setClass重新指定Activity,同時我們把目標activity的絕對路徑也傳遞給LoginActivity,用於登入後的自動跳轉。這樣我們就成功跳轉到了LoginActivity,並且攜帶了目標activity的啟動引數。
在LoginActivity中假如我們正確輸入了使用者名稱和密碼,成功登陸了,那麼在成功後的介面中我們進行這樣的處理

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方法是我們登入成功後的回撥方法,首先我們獲取目標Activity的絕對路徑,這裡進行了一次判斷,如果我們是直接啟動的登入介面是沒有目標Activity的,所以直接finish,如果有那麼通過setClassName設定啟動的目標activity後直接通過這個intent啟動,注意此時這個intent中還攜帶了我們目標activity中需要的引數,這樣登入成功後就成功跳轉到了目標activity,引數也正常的傳遞了。到此整個流程分析完畢。

最後當我們在activit中使用時,直接在Activit中呼叫

checkLoginToStart<UserCenterActivity>()複製程式碼

如果你需要給Activity傳遞引數 則

checkLoginToStart<UserCenterActivity>(KEY to VALUE)複製程式碼

這樣一來少了一層邏輯判斷,程式碼可讀性也更高。

相關文章