【问题标题】:Create a callback using a lambda使用 lambda 创建回调
【发布时间】:2019-10-29 08:53:23
【问题描述】:

我很难弄清楚如何使用 lambda 在 Kotlin 中创建回调。我有一个自定义 TextInputEditText,我想实现一个函数,该函数可以在文本更改时调用。

这是我的自定义 EditText:

class EditTextEx : TextInputEditText, TextWatcher {
    constructor(context: Context?) : super(context)
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)


    override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
      // Call the callback onTextAvailable with the EditText's text (s.toString)
    }

    override fun afterTextChanged(p0: Editable?) {
    }

    override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
    }

}

在我的活动中,我希望在调用 onTextChanged 事件时调用回调。自定义控件中的回调仅将文本发送回客户端。所以在我的活动中,我想要这样的东西:

editText.onTextAvailable(text -> do something )

【问题讨论】:

    标签: android kotlin lambda


    【解决方案1】:

    试试这样的:

    fun getEditTextChange(editText: EditText, onTextChange: (String) -> Unit){
            val tw = object: TextWatcher {
                private var region = Locale.getDefault().language
    
                override fun afterTextChanged(s: Editable?) {
                    onTextChange.invoke(s.toString())
                }
    
                override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
                override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
    
            }
            editText.addTextChangedListener(tw)
        }
    

    希望对你有帮助

    【讨论】:

      【解决方案2】:

      其实很容易做到,看:

      inline fun EditText.onTextChanged(crossinline onTextChange: (String) -> Unit): TextWatcher {
          val textWatcher = object: TextWatcher {
              override fun afterTextChanged(editable: Editable) {
                  onTextChange(editable.toString())
              }
      
              override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
              override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
          }
          this.addTextChangeListener(textWatcher)
          return textWatcher
      }
      

      现在你可以打电话了

      editText.onTextChanged { text -> /* do something */ }
      

      【讨论】:

      • 所以回调主要是使用扩展函数完成的?我遇到了这个但想不通:stackoverflow.com/a/48761541/11647945 这是完成同样事情的不同方法吗?
      • 不完全是,扩展只是为给定类提供新功能的一种方式,回调只是你可以把它放在任何地方的接口
      • 您可以使用扩展函数将回调方法包装成您喜欢的签名。
      【解决方案3】:

      除了@EpicPandaForce 的解决方案,还有其他几个解决方案。如果您想坚持使用示例中所示的类,则可以这样做:

      class EditTextEx : TextInputEditText, TextWatcher {
          constructor(context: Context?) : super(context)
          constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
          constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
      
          private var mOnTextWatcherCallback: (m: String) -> Unit = {}
      
          override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
              if (mOnTextWatcherCallback != null)
                  mOnTextWatcherCallback(s.toString())
          }
      
          override fun afterTextChanged(p0: Editable?) {
          }
      
          override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
          }
      
          fun onTextChange(callback: (text: String) -> Unit) {
              mOnTextWatcherCallback = callback
          }
      }
      

      然后在你的活动中创建一个函数:

      fun onTextChange(text: String) {
        // Do something with the text.
      }
      

      然后设置你的回调如下:

      my_edittext.onTextChange(::onTextChange)
      

      此解决方案允许您将相同的 onTextChange 函数重新用于其他想要使用它的控件。

      如果您更喜欢使用接口来定义回调,请执行以下操作:

      class EditTextEx : TextInputEditText, TextWatcher {
          constructor(context: Context?) : super(context)
          constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
          constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
      
          private var mOnTextWatcherCallback: ITextWatcher? = null
      
          override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
              if (mOnTextWatcherCallback != null)
                  mOnTextWatcherCallback!!.onTextChanged(s.toString())
          }
      
          override fun afterTextChanged(p0: Editable?) {
          }
      
          override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
          }
      
          fun onTextChange(callback: ITextWatcher) {
              mOnTextWatcherCallback = callback
          }
      }
      

      然后在您的活动中,按如下方式创建回调:

      val textChangeHandler = object: ITextWatcher {
          override fun onTextChanged(text: String) {
              var t = text
          }
      }
      

      然后为您的 edittext 控件设置回调,如下所示:

      my_edittext.onTextChange(textChangeHandler)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-05
        • 2015-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-18
        • 2018-07-09
        相关资源
        最近更新 更多