Pra*_*nav 11 android mvvm android-databinding
我正在使用Android数据绑定框架我假设一个EditText用于登录表单,用户名如下所示
<EditText
android:id="@+id/etext_uname"
style="@style/login_edittext"
android:hint="@string/hint_username"
android:inputType="textEmailAddress" />
Run Code Online (Sandbox Code Playgroud)
我也定义了LoginViewModel但我需要帮助如何在用户输入错误的电子邮件地址时在edittext中设置错误在某些事件中让我们说
public void afterTextChanged(@NonNull final Editable editable)
Run Code Online (Sandbox Code Playgroud)
因为据我所知,在传统Android方法中我们可以通过et.setError()方法以编程方式执行此操作,但我不想通过Activity或Fragment创建edittext对象.
如果你想EditText.setError()用数据绑定做一些功能,这里有两个方法.
方法1
使用从数据绑定生成的最终EditText视图(https://developer.android.com/topic/libraries/data-binding/index.html#views_with_ids)
您可以直接调用EditText而无需手动创建它,因为它是在您为视图设置id后自动生成的(对于包含的布局也是如此).
MainActivityBinding.etext_uname.setError("Wrong email format");
Run Code Online (Sandbox Code Playgroud)
要么
MainActivityBinding.etext_uname.addTextChangedListener(new MyOwnTextWatcher());
Run Code Online (Sandbox Code Playgroud)
方法2
如果你想像乔治亚提到的那样使用xml的绑定方法(https://medium.com/google-developers/android-data-binding-custom-setters-55a25a7aea47#.su88ujqrn)
首先,您必须设置自己的绑定方法.建议为所有绑定方法创建另一个类.
方法必须是静态的,带有@BindingAdapter注释和相应的绑定方法名称(Namespace和方法名称可以自定义)
1.设置自定义TextWatcher
public class MyOwnBindingUtil {
public interface StringRule {
public boolean validate(Editable s);
}
@BindingAdapter("android:watcher")
public static void bindTextWatcher(EditText pEditText, TextWatcher pTextWatcher) {
pEditText.addTextChangedListener(pTextWatcher);
}
@BindingAdapter(value = {"email:rule", "email:errorMsg"}, requireAll = true)
public static void bindTextChange(final EditText pEditText, final StringRule pStringRule, final String msg) {
pEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (!pStringRule.validate(s)) {
pEditText.setError(msg);
}
}
});
}
/*
Your other custom binding method
*/
}
Run Code Online (Sandbox Code Playgroud)
如果要使用自定义操作设置自己的TextWatcher,如显示的Toast,则显示Dialog.你应该使用"android:watcher"方法
mBinding.setWatcher(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
Run Code Online (Sandbox Code Playgroud)
在xml中,
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:email="http://schemas.android.com/tools"
>
<data>
<variable
name="watcher"
type="android.text.TextWatcher"/>
<variable
name="emailRule"
type="example.com.testerapplication.MyOwnBindingUtil.StringRule"/>
<variable
name="errorMsg"
type="java.lang.String"/>
</data>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Input Email"
android:watcher="@{watcher}
/>
Run Code Online (Sandbox Code Playgroud)
2.设置您自己的验证规则和错误消息
如果你想使用setError函数,只留下errorMsg和验证逻辑进行自定义.您可以像下面那样设置xml.
在xml中,
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:email="http://schemas.android.com/tools"
>
<data>
<variable
name="watcher"
type="android.text.TextWatcher"/>
<variable
name="emailRule"
type="example.com.testerapplication.MyOwnBindingUtil.StringRule"/>
<variable
name="errorMsg"
type="java.lang.String"/>
</data>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Input Email"
email:rule="@{emailRule}"
email:errorMsg="@{errorMsg}"
/>
Run Code Online (Sandbox Code Playgroud)
活动代码
mBinding.setErrorMsg("Wrong type");
mBinding.setEmailRule(new MyOwnBindingUtil.StringRule() {
@Override
public boolean validate(Editable s) {
// check if the length of string is larger than 18
return s.toString().length() > 18;
}
});
Run Code Online (Sandbox Code Playgroud)
请随意编辑我的代码,使开发人员使用的绑定更通用.
从根本上来说,您需要一种实现依赖字段的方法。错误取决于文本的值。您希望在文本更改时更新错误值。
我找到了两种方法来实现这一目标:
<EditView
android:text="@={viewModel.email}"
android:error="@={viewModel.emailRule.check(email)} />
Run Code Online (Sandbox Code Playgroud)
数据绑定确保每当更改check时都会调用该函数。email
我编写了一个实用程序来在ObservableField和之间进行转换Observable。参见FieldUtils.java
使用它,您可以在 ViewModel/Model 代码中实现。
public class ViewModel {
ObservableField<String> email = new ObservableField<>();
ObservableField<String> emailError = toField(toObservable(email).map(new Func1<String, String>() {
@Override
public String call(String email) {
return FormUtils.checkEmail(email) ? null : "Invalid Email";
}
}));
}
Run Code Online (Sandbox Code Playgroud)
EditText 在用户键入时清除错误。数据绑定期望在调用 setter 后保留属性的值。因此,如果值没有改变,它不会再次调用 setter。因此,只要您输入,如果计算出的错误值相同,数据绑定将不会调用 setter,因此错误将消失。这种类型使得error属性与数据绑定不兼容。
我更喜欢使用设计库提供的TextInputLayout 。它有一个持久的错误字段,而且看起来也更好。
| 归档时间: |
|
| 查看次数: |
9067 次 |
| 最近记录: |