如何在Android上为EditText数据绑定到onTextChanged?

Nil*_*zor 34 android android-databinding

Yigit博伊尔和乔治·芒特对Android的数据绑定的谈话,他们说明它是多么容易绑定到TextWatcheronTextChanged(在13:41).在按钮上.他们的幻灯片错了吗?首先,ButtonView没有onTextChanged属性.它既没有setOnTextChanged方法.也没有EditText.但他们都有addTextChangedListener一个TextWatcher输入.

那他们在说什么呢?他们是如何做到的呢?他们的示例代码无法编译,但会出现此错误:

Error:(17) No resource identifier found for attribute 'onTextChanged' in package 'android'
Run Code Online (Sandbox Code Playgroud)

如何使用Android Databinding框架绑定到任何View或特别是EditText上的"Text Changed Event"?

Nil*_*zor 74

实际上它开箱即用.我认为我的错误是使用旧版本的数据绑定框架.使用最新的,这是程序:

视图:

<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/username"
    android:text="Enter username:"
    android:onTextChanged="@{data.onTextChanged}" />
Run Code Online (Sandbox Code Playgroud)

模型:

public void onTextChanged(CharSequence s, int start, int before, int count) {
    Log.w("tag", "onTextChanged " + s);
}
Run Code Online (Sandbox Code Playgroud)

确保您参考了gradle构建工具v1.5.0或更高版本,并android.dataBinding.enabled true在build.gradle中启用了数据绑定.

编辑:在这里运行演示项目.查看.模特.

  • 此解决方案不起作用.EditText没有onTextChanged属性. (9认同)
  • @ M.Palsich它只是工作.https://news.realm.io/news/data-binding-android-boyar-mount/ (3认同)
  • 这不起作用,只是试过了。不知道它是如何被接受的,也不知道你们中的任何人是如何让它发挥作用的 (3认同)
  • 是的 EditText 不需要 onTextChanged 属性,因为它被定义为 BindingAdapter:https://android.googlesource.com/platform/frameworks/data-binding/+/android-6.0.0_r7/extensions/baseAdapters/src/main /java/android/databinding/adapters/TextViewBindingAdapter.java#299。tl;dr:数据绑定很神奇。 (2认同)

Mic*_*cer 40

要扩展@Nilzors答案,还可以在布局中传递文本和/或其他参数:

视图:

<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/username"
    android:text="Enter username:"
    android:onTextChanged="@{(text, start, before, count) -> viewModel.onUsernameTextChanged(text)}" />
Run Code Online (Sandbox Code Playgroud)

视图模型:

public void onUsernameTextChanged(CharSequence text) {
    // TODO do something with text
}
Run Code Online (Sandbox Code Playgroud)

您始终需要传递零或所有参数.

  • 如果您已在项目中正确设置数据绑定,那么您已准备好一些绑定适配器,这就是其中之一.请参阅https://android.googlesource.com/platform/frameworks/data-binding/+/android-6.0.0_r7/extensions/baseAdapters/src/main/java/android/databinding/adapters/TextViewBindingAdapter.java#299并查看其他评论吼叫@Nilzor的回答. (5认同)
  • 不工作!它说 onTextChanged 不是一个属性 (4认同)
  • 如何为 afterTextChange 方法编写这个?我不想将任何数据传递给方法,我将从 LiveData 本身获取文本。 (2认同)

Khe*_*raj 15

简单的方法

如果您使用的是onTextChange()模型更新的文本,那么你可以直接使用双向绑定

<data>
    <variable
        name="user"
        type="com.package.User"/>
</data>

<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@={user.name}"/>
Run Code Online (Sandbox Code Playgroud)

您的模型班级将具有gettersetter

public class User {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,模型名称将通过用户交互实时更改。因此,无论何时使用binding.getUser().getName(),您都会获得最新的文本。

单向绑定仅在更改模型值时才会更新。它不会实时更新模型。

android:text="@{user.name}"
Run Code Online (Sandbox Code Playgroud)

双向绑定可通过用户输入实时更新模型变量。

android:text="@={user.name}"
Run Code Online (Sandbox Code Playgroud)

唯一的区别=(等号)接收属性的数据更改并同时侦听用户更新


sma*_*871 12

如果您只需要text文本更改后的参数,您可以使用android:afterTextChanged绑定适配器。例如:

android:afterTextChanged="@{(text) -> viewModel.onTextChange(text)}"
Run Code Online (Sandbox Code Playgroud)

然后在你ViewModel刚刚的实现中像这样:

fun onTextChange(editable: Editable?) {
    Log.d("TAG","New text: ${editable.toString()}")
}
Run Code Online (Sandbox Code Playgroud)

此外,还有android:beforeTextChanged用于在文本更改事件之前了解旧文本的命令,用法与 相同android:afterTextChanged


Ash*_*kol 5

我使用此方法处理 android databinding.1st 中的文本更改侦听器,在您的ViewModel类中创建LiveData变量,并创建返回LiveData对象的getText方法。

  • public MutableLiveData<String> verifyCodes = new MutableLiveData<>();
  • public LiveData<String> getCodes(){ return verifyCodes; }

然后在你的 xml 文件editText字段设置属性上的文本绑定与上面的 liveData 字段

  • <EditText android:id="@+id/et_verification1st" android:layout_width="match_parent" android:layout_height="match_parent" android:text="@={viewModel.verifyCodes}"/>

在数据绑定中,您已经知道如何在数据标签内创建 viewModel 类的变量,我相信。例如

  • <data> <variable name="viewModel" type="viewModel.VerifyUserActivityViewModel" /> </data>

好的,现在您的活动必须观察我们在 viewModel 类中创建的 liveData 对象

  • mViewModel.getCodes().observe(this,new Observer< String>(){ @Override public void onChange(String strings){ log.d("OnChange",strings); }});

onChange方法中更改文本时,您可以执行任何逻辑


小智 5

1. 在您的 BindingAdapter 类中,记下此内容。在这里,我传递了 viewModel,以便我们可以针对特定 viewModel 执行特定任务:

@BindingAdapter("app:addTextChangeListener")
fun addTextChangeListener(view: EditText, viewModel: ViewModel) {

    view.addTextChangedListener(object : TextWatcher {
        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        }

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

        override fun afterTextChanged(s: Editable?) {
            when (viewModel) {
                is LoginViewModel -> viewModel.invisibleErrorTexts()
            }
        }

    })

}

Run Code Online (Sandbox Code Playgroud)

2. 在 XML 的 Edittext 中,输入下面给出的属性: 这里“viewModel”是我的布局标记中 LoginViewModel 的变量名称

app:addTextChangeListener="@{viewModel}"
Run Code Online (Sandbox Code Playgroud)