在Yigit Boyar and George Mount's talk on Android Databinding中,他们说明了绑定到TextWatcher
的onTextChanged
是多么容易(13:41)。在按钮上。他们的幻灯片错了吗?首先,Button
View没有onTextChanged
属性。它既没有setOnTextChanged
方法。 EditText
也没有。但他们都有addTextChangedListener
,以TextWatcher
为输入。
那他们在说什么呢?他们是如何做到的呢?他们的示例代码无法编译,但会出现此错误:
Error:(17) No resource identifier found for attribute 'onTextChanged' in package 'android'
如何使用Android Databinding框架绑定到任何View或特别是EditText上的“Text Changed Event”?
实际上它开箱即用。我认为我的错误是使用旧版本的数据绑定框架。使用最新的,这是程序:
视图:
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/username"
android:text="Enter username:"
android:onTextChanged="@{data.onTextChanged}" />
模型:
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.w("tag", "onTextChanged " + s);
}
确保您引用了gradle构建工具v1.5.0或更高版本,并在build.gradle中启用了与qazxsw poi的数据绑定。
要扩展@Nilzors答案,还可以在布局中传递文本和/或其他参数:
视图:
model
视图模型:
<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)}" />
您始终需要传递零或所有参数。
如果您使用public void onUsernameTextChanged(CharSequence text) {
// TODO do something with text
}
在模型中更新文本,那么您可以直接使用onTextChange()
。
Two-way Binding
你的模特课将有<data>
<variable
name="user"
type="com.package.User"/>
</data>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@={user.name}"/>
和getter
。
setter
现在,模型中的名称将通过用户交互实时更改。因此,每当使用public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
时,您将获得最新文本。
单向绑定仅在模型值更改时才会更新。它不会实时更新模型。
binding.getUser().getName()
双向绑定更新模型变量实时与用户输入。
android:text="@{user.name}"
唯一的区别在于单向和双向绑定中的android:text="@={user.name}"
(等号)。
最好的方法是添加绑定适配器和文本观察器。
=
并在您的xml中将此attr添加到您的编辑文本中
public class Model{
private TextWatcher textWatcher;
public Model(){
this.textWatcher= getTextWatcherIns();
}
private TextWatcher getTextWatcherIns() {
return new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
//do some thing
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//do some thing
}
@Override
public void afterTextChanged(Editable s) {
//do some thing
}
};
}
public TextWatcher getTextWatcher() {
return textWatcher;
}
public void setTextWatcher(TextWatcher textWatcher) {
this.textWatcher = textWatcher;
}
@BindingAdapter("textChangedListener")
public static void bindTextWatcher(EditText editText, TextWatcher textWatcher) {
editText.addTextChangedListener(textWatcher);
}
}
将<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:textChangedListener="@{model.textWatcher}" />
附加到setOnFocusChangeListener
,并使用文本内容与全局变量(该字段的先前状态/内容)进行比较,以确定它是否已更改:
EditText
代码不应该运行。根据API文档,TextView和EditText都没有“onTextChanged”XML属性。它们确实支持“addTextChangedListener”方法,但我不确定它如何与数据绑定一起使用。
mEditTextTitle.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus)
// check if text has changed
}
});
https://developer.android.com/reference/android/widget/TextView.html