如何利用Kotlin实现极简回调
前言
在各种开发场景中,回调都有着广泛的应用,命名往往是各种Callback和Listener,其中在Android中接触最早也最常用的可能就是View.OnClickListener了。
mBtn.setOnClickListener(newView.OnClickListener(){
@Override
publicvoidonClick(Viewv){
Log.d("MM","Click");
}
});
不过写多了也有点烦恼,我只想打印一条日志,却写了这么多代码。不过好在这个接口里面只包含一个方法,但换做一些包含方法数量比较多的回调就显得比较臃肿了:
mEdit.addTextChangedListener(newTextWatcher(){
@Override
publicvoidbeforeTextChanged(CharSequences,intstart,intcount,intafter){
}
@Override
publicvoidonTextChanged(CharSequences,intstart,intbefore,intcount){
}
@Override
publicvoidafterTextChanged(Editables){
}
});
如果你想优化你的代码,让它们看起来更简洁优雅,可以试试Kotlin的中的一些方法。
简化
先来看下Kotlin中的回调:
mBtn.setOnClickListener(object:View.OnClickListener{
overridefunonClick(v:View?){
println("Click")
}
})
好像一点也没简化嘛,不过因为在Kotlin里函数也是参数的一种,在Java中只包含一个方法的接口,在Kotlin中都可以使用Lambda表达式来达成一样的效果。
mBtnCallback.setOnClickListener{println("Click")}
是不是简单很多了,但上面的用法仅适用于接口中只有一个方法的情况,如果存在多个方法的话,当然也可以简化了:
mEdit.addTextChangedListener{
beforeTextChanged{text,start,count,after->println("beforeTextChanged")}
onTextChanged{text,start,before,count->println("onTextChanged")}
afterTextChanged{text->println("afterTextChanged")}
}
也可以按需调用其中任意个方法:
mEdit.addTextChangedListener{
onTextChanged{text,start,before,count->println("onTextChanged")}
}
不过此处的addTextChangedListener是一个扩展函数,需要我们来自己实现:
inlinefunTextView.addTextChangedListener(init:TextWatcherBridge.()->Unit)=addTextChangedListener(TextWatcherBridge().apply(init))
classTextWatcherBridge:TextWatcher{
privatevarbeforeTextChanged:((CharSequence?,Int,Int,Int)->Unit)?=null
privatevaronTextChanged:((CharSequence?,Int,Int,Int)->Unit)?=null
privatevarafterTextChanged:((Editable?)->Unit)?=null
overridefunbeforeTextChanged(s:CharSequence?,start:Int,count:Int,after:Int){
beforeTextChanged?.invoke(s,start,count,after)
}
overridefunonTextChanged(s:CharSequence?,start:Int,before:Int,count:Int){
onTextChanged?.invoke(s,start,before,count)
}
overridefunafterTextChanged(s:Editable?){
afterTextChanged?.invoke(s)
}
funbeforeTextChanged(listener:(CharSequence?,Int,Int,Int)->Unit){
beforeTextChanged=listener
}
funonTextChanged(listener:(CharSequence?,Int,Int,Int)->Unit){
onTextChanged=listener
}
funafterTextChanged(listener:(Editable?)->Unit){
afterTextChanged=listener
}
}
原理就是实现一个扩展函数,把我们自己实现的TextWatcherBridge加入到回调中,因为Kotlin支持函数式编程,里面都是高阶函数。为了减少性能损耗,扩展函数声明为内联函数。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。