美文网首页ANDROID
[Android] DataBinding自定义View双向绑定

[Android] DataBinding自定义View双向绑定

作者: Speronie | 来源:发表于2018-12-04 21:28 被阅读0次

    问题描述

    包含EditText的自定义View需要实现双向绑定,即在用户输入时,对应的Observable变量能够实时获取最新值。

    实现方案

    适用BindingAdapter实现EditText文本的set方法。在赋值前需要判断是否与原值相等,如果相等则不重新set,因为set方法会触发下面的get方法,若不判断是否相等会引起死循环。

    @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进行绑定,监听value属性的Setter事件,做到双向绑定。

    @InverseBindingAdapter(attribute = "value", event = "valueAttrChanged")
    public static String getValue(CustomLayout customLayout) {
        return customLayout.etContent.getText().toString();
    }
    

    为EditText添加TextWatcher,监听内容变化,触发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获取更新后的数据。

     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();
        }
    });
    

    相关文章

      网友评论

        本文标题:[Android] DataBinding自定义View双向绑定

        本文链接:https://www.haomeiwen.com/subject/pnzvcqtx.html