起因:
原文: https://blog.csdn.net/u011133887/article/details/123004000
推送: https://mp.weixin.qq.com/s/TTq709cPl8rMW7ipMF57_g
demo
fun A.extendsf(ry: TextWaterDslImpl.() -> Unit) {
val tvdslI = TextWaterDslImpl()
ry.invoke(tvdslI)
this.addList(tvdslI)
}
fun main() {
val a=A()
a.extendsf {
beforeTv {
println("开始")
println(it)
}
}
a.doa1()
}
class TextWaterDslImpl : TvWater {
private var bTvM1: ((s1: String) -> Unit)? = null
private var bTvM2: ((s1: String, s2: String) -> Unit)? = null
fun beforeTv(method: (s1: String) -> Unit) {
bTvM1 = method
}
fun afterTv(method: (s1: String, s2: String) -> Unit) {
bTvM2 = method
}
override fun beforeTv(str: String) {
bTvM1?.invoke(str)
}
override fun afterTv(s1: String, s2: String) {
bTvM2?.invoke(s1, s2)
}
}
interface TvWater {
fun beforeTv(str: String)
fun afterTv(s1: String, s2: String)
}
class A {
private var tv: TvWater? = null
fun addList(tv: TvWater) {
this.tv = tv
}
fun doa1() {
tv?.beforeTv("xxxdo1")
}
fun doa2() {
tv?.afterTv("xxx01", "xxx02")
}
}
其中
fun A.extendsf(ry: TextWaterDslImpl.() -> Unit) {
val tvdslI = TextWaterDslImpl()
ry.invoke(tvdslI)
this.addList(tvdslI)
}
中,TextWaterDslImpl.() -> Unit 标明 ry需要的参数类型,他是TextWaterDslImpl中任意的无参且无返回的方法。方法体中执行 ry.invoke(tvdslI) 相当于 tvdsll类设置了你传入的方法,当你调用 doa1()时,执行了rv这个方法,参数回调到 rv 的 方法体中。比较绕。
原文中:
inline fun TextView.addTextChangedListenerClosure(
crossinline afterTextChanged: (Editable?) -> Unit = {},
crossinline beforeTextChanged: (CharSequence?, Int, Int, Int) -> Unit = { charSequence, start, count, after -> },
crossinline onTextChanged: (CharSequence?, Int, Int, Int) -> Unit = { charSequence, start, after, count -> }
) {
val listener = object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
afterTextChanged.invoke(s)
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
beforeTextChanged.invoke(s, start, count, after)
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
onTextChanged.invoke(s, start, before, count)
}
}
this.addTextChangedListener(listener)
}
更好理解一点,其中方法参数,crossinline afterTextChanged: (Editable?) -> Unit = {}, 等于{}是默认空实现,把方法当参数,默认空实现,可以选择重写或者不重写。类似于:
fun main() {
doa1(str2 = "hhh")
}
fun doa1(str:String="111",str2: String="222"){
//todo
}
giao 这也太绕了 DSL
网友评论