Создать обратный звонок, используя лямбду - PullRequest
0 голосов
/ 14 июня 2019

Я с трудом пытаюсь понять, как создать обратный вызов в 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 )

Ответы [ 3 ]

1 голос
/ 14 июня 2019

Это на самом деле довольно легко сделать, посмотрите:

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 */ }
0 голосов
/ 15 июня 2019

В дополнение к решению @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)
0 голосов
/ 14 июня 2019

Попробуйте что-то вроде этого:

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

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...