【问题标题】:How to add EditText input to custom model using data binding adapter?如何使用数据绑定适配器将 EditText 输入添加到自定义模型?
【发布时间】:2026-02-02 19:05:01
【问题描述】:

这是我的数据绑定适配器:

@BindingAdapter("taskMinutes")
public static void taskMinutes(@NonNull TextView view, @NonNull Task task) {
    if (task.getDueDate() == null) {
        view.setText("");
        return;
    }
    view.setText(String.valueOf(DateUtils.getDateMinutes(task.getDueDate())));
}

xml:

app:taskMinutes="@{task}"

并且分钟在EditText 中正常显示,但没有添加到task.dueDate

但是如何添加适配器以将新输入从EditText 归档到task.dueDate

【问题讨论】:

  • 你解决了吗? :)
  • @RobertBanyai 下面的解决方案可能会对您有所帮助:)

标签: android data-binding android-databinding


【解决方案1】:

在我的情况下,我添加了一个属性“输入”并在其上实现了 inverseBinding

@BindingAdapter(value = {"input", "inputAttrChanged"}, requireAll = false)
    public static void bindIntegerInText(AppCompatEditText tv, int value, final InverseBindingListener inverseBindingListener)
    {
        tv.setText(String.valueOf(value));
        // Set the cursor to the end of the text
        tv.setSelection(tv.getText().length());

        tv.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                //inverseBindingListener.onChange();
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                inverseBindingListener.onChange();
            }

            @Override
            public void afterTextChanged(Editable s) {
                //inverseBindingListener.onChange();
            }
        });
    }


    @InverseBindingAdapter(attribute = "app:input", event = "app:inputAttrChanged")
    public static int bindCountryInverseAdapter(AppCompatEditText view) {
        String string = view.getText().toString();
        return string.isEmpty() ? 0 : Integer.parseInt(string);
    }

XML:

<android.support.v7.widget.AppCompatEditText
            android:id="@+id/et_age"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:layout_marginTop="16dp"
            android:ems="10"
            android:hint="Enter Age"
            android:inputType="number"
            app:input="@={userInfo.age}"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/et_password"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="16dp" />

我在我的模型对象中添加了一个检查以避免模型和视图之间的无限循环

@Bindable
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        Log.d("Age","Age "+age);
        if (this.age != age){
            this.age = age;
            if (this.age != 0)
            notifyPropertyChanged(BR.age);
        }
    }

还有另一种简单的方法:

#写一个类进行转换,加上这两个方法

    public class Conversion {

    @InverseMethod("toInt")
    public static String toString(int age) {
        return age == 0 ? null : String.valueOf(age);
    }

    public static int toInt(String string) {
        return string.isEmpty() ? 0 : Integer.parseInt(string);
    }
}

@InverseMethod("toInt") 表示,将调用toInt() 方法进行数据反转。

# 在 XML 中

<android.support.v7.widget.AppCompatEditText
            android:id="@+id/et_age"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:layout_marginTop="16dp"
            android:ems="10"
            android:hint="Enter Age"
            android:inputType="number"
            android:text="@={Conversion.toString(userInfo.age)}"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/et_password"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="16dp" />

#在布局文件中导入Conversion类

<import type="bytes.wit.databinding.Conversion"/>

【讨论】:

  • 第二部分是迄今为止我见过的最干净的实现,它可以在所有地方工作。如果年龄为 0,我会将 toString() 方法更改为返回“0”,否则如果将代码中的年龄设置为 0,则编辑文本将保持空白。
【解决方案2】:

我认为您应该会发现这篇文章对使用 EditText 进行转换很有用

https://medium.com/google-developers/android-data-binding-inverse-functions-95aab4b11873

您可以使用比 InverseBindingAdapers 更简单的方式执行 2 向转换函数。

【讨论】:

    【解决方案3】:

    请看一下双向数据绑定。你必须定义一个InversBindingAdapter

    【讨论】: