Kotlin 高阶函数? 自定义listener?

面试中被问到,使用kotlin的时候,如何实现监听,例如点击事件:
首先,平常开发中,Kotlin在使用期间,我们的习惯是使用已经熟悉的事务,初次听到这个的时候,有一些懵,
回答说,正常写一个interface,传一个position:Int?,一个any:Any?,实际上,这样的listener已经能面对很多
情况下的监听了,当然面试官需要的不是这样的答案,
所以,被问到,有没有用到过invoke来实现监听?
没有!!!

回程后查阅资料,大部分写的是「Kotlin自定义监听」
以下为基本代码,

正常的RecyclerView中的Adapter:
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.qiufeng.myapplication.R
import kotlinx.android.synthetic.main.item_main.view.*
class MainItemAdapter(
    private val context: Context,
    private val items: Array<String>
) : RecyclerView.Adapter<MainItemAdapter.NormalViewHolder>() {
    inner class NormalViewHolder(view: View) : RecyclerView.ViewHolder(view)
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NormalViewHolder {
        val view = LayoutInflater.from(context.applicationContext)
            .inflate(R.layout.item_main, parent, false)
        return NormalViewHolder(view)
    }
    override fun getItemCount(): Int = items.size
    override fun onBindViewHolder(holder: NormalViewHolder, position: Int) {
        holder.itemView.tv_title.text = items[position]
        holder.itemView.setOnClickListener{
            if (::onViewClick.isInitialized)onViewClick.invoke(position)
        }
    }
    lateinit var onViewClick: (position:Int) ->Unit// 无参 括号中不写
}
实际调用MainActivity.java
val adapter = MainItemAdapter(this, arrayOf("1", "2", "3", "4", "5", "6"))
rv_list.adapter = adapter
rv_list.layoutManager = LinearLayoutManager(this)
adapter.onViewClick = {
    println("当前点击到:".plus(it))
}

看到代码中没有关于adapter相关Listener的set方法,可是调用的时候却异常简单,
实际上可以理解为在Activity中获取到Adapter 对象之后,对onViewClick变量赋值,值为一个函数,
如此实现,确实可以省略开发中一些代码,也可以随时修改参数,毕竟没有固定Listener,所以不必担心会
影响其它的调用者,当然,如果有的时候追求Utils编码,还是可以写成Listener,只是在代码量上,确实invoke
过于简便,想了下,应该完全替代任何监听了,当然参数不会超过22个吧

adapter 中变量声明,对应使用方法
// lateinit 写法  A
lateinit var onViewClick: (position: Int) -> Unit
// null 写法    B
var onViewClick0: ((position: Int) -> Unit)? = null
// 无参 null 写法  C
var onViewClick1: (() -> Unit)? = null
// Adapter中调用
holder.itemView.setOnClickListener {
   // 对应lateinit var,这种写法安全
    if (::onViewClick.isInitialized) onViewClick.invoke(position)
   // 这种写法对应lateinit var不安全,如果没有调用会崩溃,
   // 涉及到声明方式
    onViewClick.invoke(position)
    // 对应 B
    onViewClick0?.invoke(position)
    // 对应 C
    onViewClick1?.invoke()
}
推荐 写法:B、C

lateinit var声明的变量,必须经历初始化后再用,本身Kotlin就是避免空指针,个人感觉lateinit var在一定程度上违反了这一原则,毕竟不会编译报错

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值