kotlin TextWatcher dsl优化,最简单分析理解
前提概念:带有接收者的函数类型
1.声明一个普通的函数
var block: (Int) -> Unit
2.声明一个带接收者的函数
var block2: Person.(Int) -> Unit
3.使用示例:
private fun test0(block: (Int) -> Unit) {
block.invoke(1)
}
fun test() {
test0 {
//it 指向 1
println()
}
}
private fun test1(block2: Person.() -> Unit) {
block2.invoke(Person("12",3))
}
fun test() {
test1 {
//this 指向 person
println(this.name)
}
}
private fun test2(person: Person, block2: Person.() -> Unit) {
block2.invoke(person)
}
fun test() {
test2(Person("123", 1)) {
//this 指向 person
println(this.name)
}
}
总结
如果想简单的理解,可以将接收者作为函数的第一个参数进行带入理解,内部使用this。
TextWatchDsl 示例
typealias FunBeforeTextChanged = (s: CharSequence?, start: Int, count: Int, after: Int) -> Unit
typealias FunOnTextChanged = (s: CharSequence?, start: Int, before: Int, count: Int) -> Unit
typealias FunAfterTextChanged = (s: Editable?) -> Unit
fun TextView.addTextChangedListenerDsl(block: TextWatchDsl.() -> Unit) {
val textWatchDsl = TextWatchDsl()
block.invoke(textWatchDsl)
this.addTextChangedListener(textWatchDsl)
}
class TextWatchDsl : TextWatcher {
var funBeforeTextChanged: FunBeforeTextChanged? = null
var funOnTextChanged: FunOnTextChanged? = null
var funAfterTextChanged: FunAfterTextChanged? = null
fun beforeTextChanged(method: FunBeforeTextChanged?) {
this.funBeforeTextChanged = method
}
fun onTextChanged(method: FunOnTextChanged?) {
this.funOnTextChanged = method
}
fun afterTextChanged(method: FunAfterTextChanged?) {
this.funAfterTextChanged = method
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
funBeforeTextChanged?.invoke(s, start, count, after)
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
funOnTextChanged?.invoke(s, start, before, count)
}
override fun afterTextChanged(s: Editable?) {
funAfterTextChanged?.invoke(s)
}
}
fun test(context: Context) {
TextView(context).addTextChangedListenerDsl {
//这里面只是存粹的函数调用,不要想太多,相当于把函数作为参数传递给 TextWatchDsl
//所以才可以随意调用1个或者多个
//同时合并起来也作为一个大的函数,触发点是在block.invoke里面
//真正的实现,还是在 TextView.addTextChangedListener 里面
beforeTextChanged { s, start, count, after ->
println("$s, $start, $count, $after")
}
onTextChanged { s, start, before, count ->
println("$s, $start, $before, $count")
}
afterTextChanged {
println(it)
}
}
}
总结:
- kotlin dsl风格能够让代码更优雅,但是也会创建多个函数,这点要注意。
- dsl里面只是函数调用,要理解dsl需要去看从哪触发这个函数调用,以及接收者在哪创建的。