Двухстороннее связывание Android при редактировании текста

Я хочу установить двустороннюю привязку для редактирования текста. Но пока получаю ошибку.

Не удалось найти событие 'textChangeAttrChanged' для типа представления 'android.widget.EditText'

Это довольно простой сценарий, но никогда не видел хороший рабочий пример.

Часть обязательных адаптеров:

 @BindingAdapter("textChange")
    @JvmStatic fun setText(view: EditText, value: String) {
        if (view.text.toString() != value) {
            view.setText(value)
        }
    }

    @BindingAdapter("textChangeAttrChanged")
    @JvmStatic fun setTextListener(view: EditText, onTextChange: ITextChange) {
        val textWatcher :  TextWatcher = object : TextWatcher {
            override fun afterTextChanged(s: Editable) {
                onTextChange.onTextChanged(view.text.toString())
            }

            override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}

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

        view.addTextChangedListener(textWatcher)
    }

    @InverseBindingAdapter(attribute = "textChange")
    @JvmStatic fun getText(editText: EditText): String {
        return editText.text.toString()
    }

И из XML:

<EditText
                android:id="@+id/et_title_input"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:ems="10"
                android:hint="@string/input_address"
                android:inputType="textPersonName"
                android:textColorHint="@color/colorGray"
                textChange="@={viewModel.searchKeyword}"
                textChangeAttrChanged="@{(text) -> viewModel.onSearchEntered(text)" // adding or removing this line doesn't give a thing
                tools:ignore="Autofill" />

1 ответ

Решение

Это не правильный способ использовать обратную привязку данных для модели представления.

Первый, EditText уже поддерживает двустороннюю привязку данных через библиотеку привязки данных, поэтому вам не нужно делать это самостоятельно.

Во-вторых, вам нужен только адаптер обратной привязки, если вы хотите настроить пользовательское представление для привязки данных. В вашем случае вам просто нужно существующее представление, которое уже настроено для привязки данных, для обновления вашего представления.

Используя "@={viewModel.searchKeyword}" В нотации вы указываете, что у вас есть свойство под названием "searchKeyword", в котором есть как метод получения, так и метод установки, и что вы хотите, чтобы библиотека привязки данных вызывала метод установки со значением из представления при его изменении.

Таким образом, все, что вам нужно сделать, это реализовать свою логику в установщике свойств. Что-то вроде этого:

@Bindable var searchKeyord : String? = null
    set(value) {
        if (field != value) {
            field = value
            onSearchEntered(value)
            notifyPropertyChanged(BR.searchKeyword)
        }
    }

Пожалуйста, ознакомьтесь с документацией привязки данных для получения дополнительной информации.

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

Другие вопросы по тегам