亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Kotlin 使用高階函數(shù)實(shí)現(xiàn)回調(diào)方式

 更新時(shí)間:2020年03月26日 10:14:20   作者:耳東_  
這篇文章主要介紹了Kotlin 使用高階函數(shù)實(shí)現(xiàn)回調(diào)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

lambda 和 高階函數(shù)

之前學(xué)習(xí)了 lambda 和高階函數(shù),然后在 android 開(kāi)發(fā)中對(duì) onClick 事件進(jìn)行監(jiān)聽(tīng)是一個(gè)很常用的功能,kotlin 的常規(guī)實(shí)現(xiàn)如下:

  rootView.setOnClickListener { view ->
    println("點(diǎn)擊了這個(gè)ID=${view.id}的view")
  }

然后在開(kāi)發(fā)中不可避免的我們也要寫(xiě)一些自定義監(jiān)聽(tīng)之類(lèi)的代碼。這個(gè)時(shí)候如果還用 java 的思想去實(shí)現(xiàn)的話(huà)就有點(diǎn)舍近求遠(yuǎn)了。

java 思想實(shí)現(xiàn)

在 java 中我們一般的做法是這樣的

定義一個(gè)接口
定義一個(gè)接口類(lèi)型變量
定義一個(gè) set 方法
調(diào)用 set 方法設(shè)置接口的實(shí)現(xiàn)類(lèi)

用 kotlin 實(shí)現(xiàn)就是如下

class MyView{
  //定義一個(gè)接口
  interface IOnLabelCheckedListener {
    fun onLabelCheck(label: String)
  }
  //定義一個(gè)接口類(lèi)型變量
  private var onLabelChecked: IOnLabelCheckedListener? = null

  private fun initView(context: Context) {
    view.setOnCheckedChangeListener { radioGroup, i ->
        onLabelChecked.onLabelCheck(radioGroup.findViewById<RadioButton>(i).text.toString())
    }
  }
  //定義一個(gè) set 方法
  fun setOnLabelCheckedListener(e: IOnLabelCheckedListener) {
    this.onLabelChecked = e
  }
}

   // 調(diào)用set方法,通過(guò)匿名內(nèi)部類(lèi)實(shí)現(xiàn)
    MyView.setOnLabelCheckedListener(object : LabelBarView.IOnLabelCheckedListener {
      override fun onLabelCheck(label: String) {

      }
    })

這樣實(shí)現(xiàn)的問(wèn)題

當(dāng)然是太復(fù)雜了。而且最初的時(shí)候這樣寫(xiě)一時(shí)搞不明白為什么 MyView.setOnLabelCheckedListener 方法內(nèi)部不能傳入 lambda 表達(dá)式,lambda 表達(dá)式的存在不就是為了替代匿名內(nèi)部類(lèi)嘛。而且如果這個(gè)接口定義的是一個(gè) java 類(lèi)型的接口就是可以用 lambda 表達(dá)式的。這是為什么?最后猜想是因?yàn)?kotlin 在和 java 互相調(diào)用的時(shí)候中間又包裹了一層,而我們直接使用 kotlin 來(lái)定義這個(gè)接口不存在中間這一層,而我們定義的 set 方法又不是一個(gè)高階函數(shù),當(dāng)然不能使用 lambda 表達(dá)式。

下面就用 kotlin 的思想來(lái)實(shí)現(xiàn)回調(diào)

使用高階函數(shù)來(lái)實(shí)現(xiàn)

kotlin 和 java 有一個(gè)重要的不同就是函數(shù)式編程。在函數(shù)式編程的思想中函數(shù)是一等公民,在使用 kotlin 時(shí)我們要多利用這種思維來(lái)思考問(wèn)題。Kotlin 中提供了高階函數(shù),它可以直接使用一個(gè)函數(shù)來(lái)作為返回值,對(duì)于習(xí)慣于 java 來(lái)編程的我來(lái)說(shuō)剛開(kāi)始理解起來(lái)有些困難,下面我把我一步一步的實(shí)現(xiàn)一個(gè)高階函數(shù)的思路寫(xiě)下,希望對(duì)大家有所幫助。

首先,能想到的就是函數(shù)傳遞,要用 lambda 來(lái)替代掉匿名內(nèi)部類(lèi)可以這樣來(lái)實(shí)現(xiàn)

//從最基礎(chǔ)的開(kāi)始做,把匿名內(nèi)部類(lèi)通過(guò) lambda 實(shí)現(xiàn)
MyView.setOnLabelCheckedListener(object : MyView.IOnLabelCheckedListener {
    override fun onLabelCheck(label: String) {
     println(label)
    }
})
// 首先 MyView.IOnLabelCheckedListener 中只有一個(gè)方法 onLabelCheck(label: String)
// 因此可以寫(xiě)出 lambda 表達(dá)式如下
var lam: (String) -> Unit = { label -> println(label) }

然后,需要把寫(xiě)好的 lambda 傳遞進(jìn)去,這個(gè)時(shí)候就要求 setOnLabelCheckedListener 方法是一個(gè)高階函數(shù)

  // 這里接收一個(gè) 上面我們改造好的表達(dá)式 lam ,它內(nèi)部實(shí)現(xiàn)應(yīng)該是把 e 賦值給當(dāng)前類(lèi)的一個(gè)對(duì)象
  fun setOnLabelCheckedListener(e: (String) -> Unit) {
    this.lisenter = e
  }
 
  //顯然 lisenter 就應(yīng)該是這樣的
  var linsnter: (String) -> Unit = {}

最后使用 linsnter 進(jìn)行回調(diào)

  private fun initView(context: Context) {
    view.setOnCheckedChangeListener { radioGroup, i ->
      linsnter(radioGroup.findViewById<RadioButton>(i).text.toString())
    }
  }

最終代碼結(jié)果:

class MyView{
  var linsnter: (String) -> Unit = {}

 private fun initView(context: Context) {
    view.setOnCheckedChangeListener { radioGroup, i ->
      linsnter(radioGroup.findViewById<RadioButton>(i).text.toString())
    }
 }

 fun setOnLabelCheckedListener(e: (String) -> Unit) { 
  this.lisenter = e
 }
}
  // 調(diào)用時(shí)將變量 lam 省略,直接使用一個(gè)表達(dá)式
  view.setOnLabelCheckedListener { label ->
    println(label)
  }

最終的代碼和之前的代碼有兩個(gè)最大的不同,一是沒(méi)有了接口定義,二是沒(méi)有了匿名內(nèi)部類(lèi)。

更好的使用高階函數(shù)

高階函數(shù)的使用更多的時(shí)候能使我們的代碼更簡(jiǎn)潔,比如下面這段代碼:

  fun refreshData(e: ((Boolean, String) -> Unit)): Boolean {

    if (!UserInfoManager.getInstance().isLogin) {
      e(false, "未登錄")
      return false
    }

    NETWorkUtils.request(ApiParamter(), object : ApiListener<ResponseData> {
      override fun onApiCompleted(data: ResponseData?) {
          e(true, "成功")
      }

      override fun onApiError(errorCode: Int, errorCodeMessage: String) {
         e(false, errorCodeMessage)
      }
    })
    return true
  }

那么在調(diào)用它的時(shí)候就可以這樣:

   mView.refreshData { isSuccess, msg ->
      //do something
  }

是不是很簡(jiǎn)單,省去了再寫(xiě)一個(gè)接口。同時(shí)如果是用 java 來(lái)調(diào)用 refreshData 方法也一樣可以的:

    mView.refreshData(new Function2<Boolean, String, Unit>() {
      @Override
      public Unit invoke(Boolean aBoolean, String s) {
        // do something
        return null;
      }
    });

Kotlin 提供了一系列的 Function 接口類(lèi)來(lái)供 java 調(diào)用高階函數(shù)時(shí)使用,最多支持22個(gè)參數(shù)有興趣的可以查看一下。

以上就是在 Kotlin 中使用高階函數(shù)來(lái)替代傳統(tǒng)的回調(diào)函數(shù)的方法。不對(duì)之處還請(qǐng)指正。希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • android 大圖片拖拽并縮放實(shí)現(xiàn)原理

    android 大圖片拖拽并縮放實(shí)現(xiàn)原理

    android 大圖片拖拽縮放有利于用戶(hù)體驗(yàn),在開(kāi)發(fā)過(guò)程中經(jīng)常使用到,這篇圖片拖拽縮放也是我在項(xiàng)目中用到的,今天整理一下,將源碼奉獻(xiàn)給大家,希望對(duì)大家以后碰到相似的問(wèn)題有幫助
    2013-01-01
  • Android studio2.3.3升級(jí)到3.1.2坑(小記)

    Android studio2.3.3升級(jí)到3.1.2坑(小記)

    這篇文章主要介紹了Android studio2.3.3升級(jí)3.1.2坑(小記),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • Android Splash界面白屏、黑屏問(wèn)題的解決方法

    Android Splash界面白屏、黑屏問(wèn)題的解決方法

    這篇文章主要為大家詳細(xì)介紹了Android Splash界面白屏、黑屏問(wèn)題的解決方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Flutter快速制作一個(gè)水印組件實(shí)例詳解

    Flutter快速制作一個(gè)水印組件實(shí)例詳解

    這篇文章主要為大家介紹了Flutter快速制作一個(gè)水印組件實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Android layoutAnimation詳解及應(yīng)用

    Android layoutAnimation詳解及應(yīng)用

    這篇文章主要介紹了Android layoutAnimation詳解及應(yīng)用的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Android不同版本兼容性適配方法教程

    Android不同版本兼容性適配方法教程

    這篇文章主要介紹了Android不同版本兼容性適配方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-11-11
  • Android Handle原理(Looper,Handler和Message)三者關(guān)系案例詳解

    Android Handle原理(Looper,Handler和Message)三者關(guān)系案例詳解

    這篇文章主要介紹了Android Handle原理(Looper,Handler和Message三者關(guān)系案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 深入理解Android中View繪制的三大流程

    深入理解Android中View繪制的三大流程

    這篇文章主要給大家介紹了關(guān)于Android中View繪制的三大流程,View的工作流程主要是指measure、layout、draw這三大流程,即測(cè)量、布局和繪制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-07-07
  • Android自定義Gallery控件實(shí)現(xiàn)3D圖片瀏覽器

    Android自定義Gallery控件實(shí)現(xiàn)3D圖片瀏覽器

    這篇文章主要介紹了Android自定義Gallery控件實(shí)現(xiàn)3D圖片瀏覽器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • android studio安裝時(shí) AVD出現(xiàn)問(wèn)題如何快速解決

    android studio安裝時(shí) AVD出現(xiàn)問(wèn)題如何快速解決

    這篇文章主要介紹了安裝android studio時(shí) AVD出現(xiàn)問(wèn)題如何快速處理,其實(shí)解決方法也很簡(jiǎn)單,文中通過(guò)截圖的形式給大家及時(shí)的非常詳細(xì),對(duì)大家的工作或?qū)W習(xí)具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03

最新評(píng)論