Kotlin回调多方法的调用代码变得简洁

·  阅读 613

背景

啰嗦的多方法回调代码影响可读性,更影响读代码人的心情,以至于不想去维护.

简单栗子,我仅需要onTextChanged方法里执行打印. afterTextChanged 和 beforeTextChanged就是多余的

    editText.addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            logd(content = "$s, $start, $before, $count");
        }
    })
复制代码

实际工作的时候,可能远不止3个方法回调.还有很多这种接口混在一起的场景.

改进

简单实现空接口

    editText.addTextChangedListener(object : TextWatcherEmptyImpl() {
       override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
           logd(content = "$s, $start, $before, $count");
       }
   })
复制代码

依赖实现如下:

// 空实现
open class TextWatcherEmptyImpl : TextWatcher {
   override fun afterTextChanged(s: Editable?) {
   }

   override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
   }

   override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
   }
}
复制代码

Kotlin闭包实现

   editText.addTextChangedListener {
       onTextChanged { s, start, before, after -> 
           logd(content = "$s,$start,$before,$after") }
   }
复制代码

依赖实现如下:

// 支持kotlin风格的扩展函数改写
fun EditText.addTextChangedListener(init: (TextWatcherKotlinImpl.() -> Unit)) =
   this.addTextChangedListener(
       TextWatcherKotlinImpl().apply { init() }
   )
   
// 支持kotlin风格的回调改写
class TextWatcherKotlinImpl(
   var beforeTextChanged: ((CharSequence?, Int, Int, Int) -> Unit)? = null,
   var onTextChanged: ((CharSequence?, Int, Int, Int) -> Unit)? = null,
   var afterTextChanged: ((Editable?) -> Unit)? = null
) : TextWatcher {


   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)
   }

   override fun afterTextChanged(s: Editable?) {
       afterTextChanged?.invoke(s)
   }

   fun beforeTextChanged(listener: ((CharSequence?, Int, Int, Int) -> Unit)) {
       beforeTextChanged = listener
   }

   fun onTextChanged(listener: ((CharSequence?, Int, Int, Int) -> Unit)) {
       onTextChanged = listener
   }

   fun afterTextChanged(listener: ((Editable?) -> Unit)) {
       afterTextChanged = listener
   }
}
复制代码

总结

方便记忆放一张图来对比下简洁度

分类:
阅读
标签:
分类:
阅读
标签:
收藏成功!
已添加到「」, 点击更改