Привязка данных - атрибут maxLength EditText

Есть ли способ предоставить атрибут android:maxLength с помощью двусторонней привязки данных в приложении Android?

В настоящее время у меня есть это в XML:

<EditText
                        android:id="@+id/edBody"
                        style="@style/SimpleEdit"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:clickable="false"
                        android:hint="@string/ComposeMessage"
                        android:text="@={viewModel.composeFace.body}"
                        android:maxLength="@={viewModel.inReplyMode ? viewModel.maxReplyLength : viewModel.maxMessageLength}"
                        android:afterTextChanged="@{viewModel.autoWatch}"
                        android:imeOptions="actionNext"
                        android:inputType="textMultiLine"/>

В модели просмотра у меня есть следующие атрибуты:

/**
 * Maximum length of message body.
 */
@Bindable
public int maxMessageLength;

/**
 * Maximum length of reply message body.
 */
@Bindable
public int maxReplyLength;

Ошибка при сборке:

> java.lang.RuntimeException: Found data binding errors.
****/ data binding error ****msg:Cannot find the getter for attribute 'android:maxLength' with value type int on android.widget.EditText.
file:...\app\src\main\res\layout\f_message_compose.xml
loc:66:20 - 77:65
****\ data binding error ****

Я понимаю, что эта ошибка возникает из-за того, что не существует простого метода установки длины текста, и она обычно предоставляется через InputFilter, как описано здесь: Как программно установить maxLength в Android TextView?

Я могу себе представить, как это работает:

android:maxLength="@={viewModel.replyLength}"

с участием

@Bindable
public InputFilter[] getReplyLength() {
    return isInReplyMode() ? new InputFilter[] { new InputFilter.LengthFilter(maxReplyLength) } : new InputFilter[] { new InputFilter.LengthFilter(maxMessageLength) };
}

но это не сработает по понятным причинам. Фактически это приводит к:

> java.lang.RuntimeException: Found data binding errors.
****/ data binding error ****msg:The expression ((viewModelInReplyMode) ? (viewModelMaxReplyLength) : (viewModelMaxMessageLength)) cannot cannot be inverted: The condition of a ternary operator must be constant: android.databinding.tool.writer.KCode@7f305219
file:...\app\src\main\res\layout\f_message_compose.xml
loc:74:50 - 74:126
****\ data binding error ****

Итак, есть ли какой-либо способ привязать атрибут максимальной длины к привязке данных?


person Pepa Novotný    schedule 07.03.2017    source источник
comment
есть BindingAdapter для android:maxLength, см .: androidxref.com/7.1.1_r6/xref/frameworks/data-binding/, для чего вам нужна двусторонняя привязка?   -  person pskink    schedule 08.03.2017
comment
Что ж, если я правильно понимаю, этот адаптер должен использоваться по умолчанию. В любом случае ваш вопрос привел меня к проблеме. Похоже, мне не следовало ставить @= перед атрибутом, а использовать только @! В этом разница между привязкой данных и двусторонней привязкой данных. Похоже, я пропустил это в спецификации :)   -  person Pepa Novotný    schedule 08.03.2017
comment
@= используется, когда напр. EditText хочет связать какую-то строку модели и отобразить ее как содержимое и обратно, когда вы ее измените, изменения должны быть сопоставлены с моделью строки   -  person pskink    schedule 08.03.2017
comment
Да, теперь я понимаю разницу, и она явно была вызвана моим невниманием к синтаксису привязки данных и, следовательно, использованием двухсторонней привязки данных вместо простой привязки данных для несоответствующего атрибута. Спасибо, что указали на это :)   -  person Pepa Novotný    schedule 08.03.2017
comment
Вместо редактирования ответьте на свой вопрос самостоятельно, если он был решен вами с помощью одного из комментариев.   -  person tynn    schedule 08.03.2017
comment
хорошо, спасибо за подсказку - я могу принять его завтра, через 48 часов   -  person Pepa Novotný    schedule 08.03.2017


Ответы (1)


Как было указано @pskink в комментариях, моя проблема заключалась в использовании двусторонней привязки данных вместо привязки данных для атрибута maxLength. Там должен быть:

android:maxLength="@{viewModel.inReplyMode ? viewModel.maxReplyLength : viewModel.maxMessageLength}"

вместо

android:maxLength="@={viewModel.inReplyMode ? viewModel.maxReplyLength : viewModel.maxMessageLength}"

Вот почему не было исключения «нет метода получения для атрибута android: maxLength TextView».

person Pepa Novotný    schedule 08.03.2017