問題描述
包含EditText的自定義View需要實現(xiàn)雙向綁定,即在用戶輸入時帮坚,對應的Observable變量能夠實時獲取最新值。
實現(xiàn)方案
適用BindingAdapter實現(xiàn)EditText文本的set方法。在賦值前需要判斷是否與原值相等,如果相等則不重新set祭椰,因為set方法會觸發(fā)下面的get方法臭家,若不判斷是否相等會引起死循環(huán)疲陕。
@BindingAdapter("value")
public static void setValue(CustomLayout customLayout, String value) {
if (customLayout != null) {
String edTextString = customLayout.etContent.getText() == null ? "" : customLayout.etContent.getText().toString();
value = value == null ? "" : value;
if (edTextString.equalsIgnoreCase(value)) {
return;
}
customLayout.setValue(value);
}
}
將屬性value與event名為“valueAttrChanged”的InverseBindingListener進行綁定,監(jiān)聽value屬性的Setter事件钉赁,做到雙向綁定蹄殃。
@InverseBindingAdapter(attribute = "value", event = "valueAttrChanged")
public static String getValue(CustomLayout customLayout) {
return customLayout.etContent.getText().toString();
}
為EditText添加TextWatcher,監(jiān)聽內容變化你踩,觸發(fā)InverseBindingListener的onChange()方法诅岩。
@BindingAdapter(
value = {"android:beforeTextChanged",
"android:onTextChanged",
"android:afterTextChanged",
"valueAttrChanged"},
requireAll = false)
public static void setTextWatcher(
CustomLayout view,
final TextViewBindingAdapter.BeforeTextChanged before,
final TextViewBindingAdapter.OnTextChanged on,
final TextViewBindingAdapter.AfterTextChanged after,
final InverseBindingListener valueAttrChanged) {
TextWatcher newWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (before != null) {
before.beforeTextChanged(s, start, count, after);
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (on != null) {
on.onTextChanged(s, start, before, count);
}
if (valueAttrChanged != null) {
valueAttrChanged.onChange();
}
}
@Override
public void afterTextChanged(Editable s) {
if (after != null) {
after.afterTextChanged(s);
}
}
};
TextWatcher oldWatcher = ListenerUtil.trackListener(view, newWatcher, R.id.textWatcher);
if (oldWatcher != null) {
view.etContent.removeTextChangedListener(oldWatcher);
}
view.etContent.addTextChangedListener(newWatcher);
}
綁定方式
在xml中通過@={}的方式綁定Observable變量讳苦。為Observable變量添加Observable.OnPropertyChangedCallback獲取更新后的數(shù)據(jù)。
app:value="@={viewModel.observedValue}"
public ObservableField<String> observedValue = new ObservableField<>("");
observedValue.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
@Override
public void onPropertyChanged(Observable sender, int propertyId) {
String changeResult = observedValue.get();
}
});