如何利用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支持函数式编程,里面都是高阶函数。为了减少性能损耗,扩展函数声明为内联函数。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。