-
kotlin(RecyclerView)多方法回调,单方法回调利用Lambda表达式进行简化
用喜欢的RecyclerView作为例子,来记录一下kotlin中多回调和单回调的简化,kotlin确实是一个比较有趣的语言。
当然,也可以利用java风格去写,不过代码会略显臃肿,也体现不出kotlin的独特之处。下面就记录一下这个时刻。
- 一、单方法回调
- 不需要定义接口,只定义一个函数变量
lateinit var mListener: (String) -> Unit
- adapter设置回调监听
fun setListener(listener: (String) -> Unit) { this.mListener = listener }
- 二、多方法回调
- 需要先定义一个接口
/** * 定义一个回调接口 */ interface SimpleCallback { fun onSuccess(response: String) fun onFailed(errorCode: Int, msg: String) }
- 按照惯例,定义一个builder
/** * 定义个Builder,简化回调接口 */ class Builder : SimpleCallback { // 定义一个函数变量 private lateinit var onSuccessVal: (response: String) -> Unit // 给函数变量赋值 fun onSuccessFun(listener: (response: String) -> Unit) { this.onSuccessVal = listener } // 回调方法 override fun onSuccess(response: String) { onSuccessVal.invoke(response) } // 定义一个函数变量 private lateinit var onFailedVal: (errorCode: Int, msg: String) -> Unit // 给函数变量赋值 fun onFailedFun(listener: (errorCode: Int, msg: String) -> Unit) { this.onFailedVal = listener } // 回调方法 override fun onFailed(errorCode: Int, msg: String) { onFailedVal.invoke(errorCode, msg) } }
- 定义回调接口的函数变量
private lateinit var listener: SimpleCallback
- 设置回调监听
fun setSimpleListener(listener: Builder.() -> Unit) { val builder = Builder() builder.listener() this.listener = builder }
- 在adapter中定义点击方法,进行回调
override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.content.text = list[position] // 这是单一回调函数的点击监听方法 holder.content.setOnClickListener { this.mListener(holder.content.text as String) } // 这是多回调方法的点击监听方法 holder.content.setOnClickListener { this.listener.onSuccess(holder.content.text as String) this.listener.onFailed(1, holder.content.text as String) } }
最后贴出Adapter和Activity的代码
- Adapter代码
class MyRecyclerViewAdapter : RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder>() { private var list: List<String> = listOf() override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder { val view: View = View.inflate(viewGroup.context, R.layout.item_recyclerview, null) return ViewHolder(view) } override fun getItemCount(): Int { return list.size } override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.content.text = list[position] // 这是单一回调函数的点击监听方法 holder.content.setOnClickListener { this.mListener(holder.content.text as String) } holder.content.setOnClickListener { this.listener.onSuccess(holder.content.text as String) this.listener.onFailed(1, holder.content.text as String) } } class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { val content: TextView = view.findViewById(R.id.tv_con) } fun setData(list: List<String>) { this.list = list notifyDataSetChanged() } //这是单一函数回调 lateinit var mListener: (String) -> Unit fun setListener(listener: (String) -> Unit) { this.mListener = listener } private lateinit var listener: SimpleCallback fun setSimpleListener(listener: Builder.() -> Unit) { val builder = Builder() builder.listener() this.listener = builder } /** * 定义一个回调接口 */ interface SimpleCallback { fun onSuccess(response: String) fun onFailed(errorCode: Int, msg: String) } /** * 定义个Builder,简化回调接口 */ class Builder : SimpleCallback { // 定义一个函数变量 private lateinit var onSuccessVal: (response: String) -> Unit // 给函数变量赋值 fun onSuccessFun(listener: (response: String) -> Unit) { this.onSuccessVal = listener } // 回调方法 override fun onSuccess(response: String) { onSuccessVal.invoke(response) } // 定义一个函数变量 private lateinit var onFailedVal: (errorCode: Int, msg: String) -> Unit // 给函数变量赋值 fun onFailedFun(listener: (errorCode: Int, msg: String) -> Unit) { this.onFailedVal = listener } // 回调方法 override fun onFailed(errorCode: Int, msg: String) { onFailedVal.invoke(errorCode, msg) } } }
- Activity代码
package com.schema.kotlin_study import android.content.Context import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView import android.util.Log import android.view.View import android.widget.Toast import java.util.concurrent.Executors class MainActivity : AppCompatActivity(), View.OnClickListener { var rvTest: RecyclerView? = null var myRecyclerViewAdapter: MyRecyclerViewAdapter? = null var list: MutableList<String> = ArrayList() override fun onClick(v: View?) { when (v?.id) { R.id.btn_add -> addData() R.id.btn_remove -> removeData() } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) rvTest = findViewById(R.id.rv_test) initView() initData() } private fun initView() { myRecyclerViewAdapter = MyRecyclerViewAdapter() rvTest?.adapter = myRecyclerViewAdapter rvTest?.layoutManager = LinearLayoutManager(this) for (i in 0..10) { list.add(i.toString()) } // 单函数回调设置 //myRecyclerViewAdapter?.setListener { Toast.makeText(this, it, Toast.LENGTH_SHORT).show() } // 多函数回调设置, 在这个地方,可以实现一个方法,也可以都实现 myRecyclerViewAdapter?.setSimpleListener { onSuccessFun { it.toast(this@MainActivity) it.loge() } onFailedFun { errorCode, msg -> (errorCode.toString(10) + msg).toast(this@MainActivity) (errorCode.toString(10) + msg).loge() } } /** 这里就是只实现一个方法 myRecyclerViewAdapter?.setSimpleListener { onSuccessFun { it.toast(this@MainActivity) it.loge() } }*/ } private fun initData() { myRecyclerViewAdapter?.setData(list) } private fun Any.toast(context: Context, duration: Int = Toast.LENGTH_SHORT): Toast { return Toast.makeText(context, this.toString(), duration).apply { show() } } private fun Any.loge(TAG: String = this@MainActivity.localClassName) { Log.e(TAG, this.toString()) } }
- 最后贴出两个工具类,也是扩展函数,打印log和显示toast。各位可以作为一个顶层函数去使用,把private去掉。
private fun Any.toast(context: Context, duration: Int = Toast.LENGTH_SHORT): Toast { return Toast.makeText(context, this.toString(), duration).apply { show() } } private fun Any.loge(TAG: String = this@MainActivity.localClassName) { Log.e(TAG, this.toString()) }