Kotlin 高级函数实现回调详解

一、前言

在开发中,我们经常使用回调函数,命名往往是各种Callback和Listener。例如最常见的View.OnClickListener

   mBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("MM","Click");
            }
        });

如果用kotlin 来写的话如下

     mBtn.setOnClickListener(object :View.OnClickListener{
            override fun onClick(v: View?) {
                Log.d("MM","Click");
            }
        })

二、自定义回调函数

在 java 中我们一般的做法是这样的

  1. 定义一个接口
  2. 定义一个接口类型变量
  3. 定义一个 set 方法
  4. 调用 set 方法设置接口的实现类

用 kotlin 实现就是如下

class MyView{
    //定义一个接口
    interface IOnListener {
        fun onCheck(str: String)
    }
    //定义一个接口类型变量
    private var mListener: IOnListener? = null

    //定义一个 set 方法
    fun setListener(onListener: IOnListener) {
        this.mListener = onListener
    }

	//完成工作后调用接口方法
	fun work(){
		mListener.onCheck("完成")
	}
	
	...
}

设置接口的实现类

      // 调用set方法,通过匿名内部类实现
        myView.setListener(object : LabelBarView.IOnLabelCheckedListener {
            override fun onLabelCheck(str: String) {
				println(str)
            }
        })

这样实现太复杂了,刚开始写的时候,觉得都没有java 的lambda表达式简洁,总觉得哪里不对。后来发现kotlin实现思想和java的不同。

三、使用高阶函数来实现

1.单方法回调

不需要定义接口,只定义一个函数变量

class MyView{

	lateinit var mListener: (String) -> Unit

	fun setListener(listener: (String) -> Unit) {
        this.mListener = listener
	}
    
    fun work(){
		mListener.onCheck("完成")
	}
	...
}

设置接口的实现类

	myView.setListener{ str ->
    	println(str)
	}

如果只有一个参数还可以这样

	//it代表入参 String类 
	myView.setListeren{ println(it) }

如果是用 java 来调用 setListener 方法也一样可以的:

    mView.setListener(new Function2<String, Unit>() {
      @Override
      public Unit invoke(String s) {
        println(s)
        return null;
      }
    });

你可能感兴趣的:(Kotlin)