Java – Data binding (bind) – maxLength property of EditText

Data binding (bind) – maxLength property of EditText… here is a solution to the problem.

Data binding (bind) – maxLength property of EditText

Is there a way to provide the android:maxLength property in Android applications via two-way data binding (bind)?

What I currently have is in XML format:

<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"/>

In the View model I have these properties:

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

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

Error thrown during build:

> 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 ****

I know this error is thrown because there is no easy way to set the text length, it is usually provided via InputFilter, as follows:
How to programmatically set maxLength in Android TextView?

I can imagine how it works like this:

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

with

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

But for obvious reasons, it won’t work. It actually causes:

> 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 ****

So is there any possible way to data bind (bind) the maximum length property?

Solution

As @pskink pointed out in the comment – my problem is using two-way data binding (bind) instead of data binding (bind) for the maxLength property. There should be:

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

Replace

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

This is why the “getter method without maxLength property of android:textView” exception appears.

Related Problems and Solutions