Может быть много способов реализовать это. Я говорю вам о двух решениях, оба хорошо работают, вы можете использовать то, что вам подходит.
Я использую extends BaseObservable
, потому что это проще, чем преобразовывать все поля в Observers
. Вы также можете использовать ObservableFields
.
Решение 1 (с использованием пользовательских BindingAdapter
)
В xml
<variable
name="model"
type="sample.data.Model"/>
<EditText
passwordValidator="@{model.password}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@={model.password}"/>
Model.java
public class Model extends BaseObservable {
private String password;
@Bindable
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
notifyPropertyChanged(BR.password);
}
}
DataBindingAdapter.java
public class DataBindingAdapter {
@BindingAdapter("passwordValidator")
public static void passwordValidator(EditText editText, String password) {
// ignore infinite loops
int minimumLength = 5;
if (TextUtils.isEmpty(password)) {
editText.setError(null);
return;
}
if (editText.getText().toString().length() < minimumLength) {
editText.setError("Password must be minimum " + minimumLength + " length");
} else editText.setError(null);
}
}
Решение 2 (с использованием пользовательских afterTextChanged
)
В xml
<variable
name="model"
type="com.innovanathinklabs.sample.data.Model"/>
<variable
name="handler"
type="sample.activities.MainActivityHandler"/>
<EditText
android:id="@+id/etPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:afterTextChanged="@{(edible)->handler.passwordValidator(edible)}"
android:text="@={model.password}"/>
MainActivityHandler.java
public class MainActivityHandler {
ActivityMainBinding binding;
public void setBinding(ActivityMainBinding binding) {
this.binding = binding;
}
public void passwordValidator(Editable editable) {
if (binding.etPassword == null) return;
int minimumLength = 5;
if (!TextUtils.isEmpty(editable.toString()) && editable.length() < minimumLength) {
binding.etPassword.setError("Password must be minimum " + minimumLength + " length");
} else {
binding.etPassword.setError(null);
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
ActivityMainBinding binding;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setModel(new Model());
MainActivityHandler handler = new MainActivityHandler();
handler.setBinding(binding);
binding.setHandler(handler);
}
}
Обновление
Вы также можете заменить
android:afterTextChanged="@{(edible)->handler.passwordValidator(edible)}"
с
android:afterTextChanged="@{handler::passwordValidator}"
Поскольку параметры совпадают с android:afterTextChanged
и passwordValidator
.