0

我正在尝试按照博客文章尝试获取两种方式的数据绑定以适用于自定义组件(其中包含 EditText 的约束视图)。

我能够让两个标准 EditText 组件与我的模型同步(两种方式),但是我无法让我的自定义组件中的更改流入我的模型(尽管数据绑定的一种方式有效)。

我的模型:

public class Model extends BaseObservable {
    private String value;

    @Bindable
    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
        notifyPropertyChanged(company.com.databinding.BR.value);
    }

    public Model() {
        value = "Value";
    }
}

活动:

@InverseBindingMethods({
        @InverseBindingMethod(
                type = CustomComponent.class,
                attribute = "value",
                method = "getValue")
})
public class MainActivity extends AppCompatActivity {
    @BindingAdapter("value")
    public static void setColor(CustomComponent view, String value) {
        if (!value.equals(view.getValue())) {
            view.setValue(value);
        }
    }

    @BindingAdapter(
            value = {"onValueChange", "valueAttrChanged"},
            requireAll = false
    )
    public static void setListeners(CustomComponent view,
                                    final ValueChangeListener onValueChangeListener,
                                    final InverseBindingListener inverseBindingListener) {
        ValueChangeListener newListener;
        if (inverseBindingListener == null) {
            newListener = onValueChangeListener;
        } else {
            newListener = new ValueChangeListener() {
                @Override
                public void onValueChange(CustomComponent view,
                                          String value) {
                    if (onValueChangeListener != null) {
                        onValueChangeListener.onValueChange(view,
                                value);
                    }
                    inverseBindingListener.onChange();
                }
            };
        }

        ValueChangeListener oldListener =
                ListenerUtil.trackListener(view, newListener,
                        R.id.textWatcher);

        if (oldListener != null) {
            view.removeListener(oldListener);
        }
        if (newListener != null) {
            view.addListener(newListener);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        binding.setModel(new Model());
    }
}

自定义组件:

public class CustomComponent extends ConstraintLayout {
    private String value;
    private EditText txt;
    private TextWatcher textWatcher;
    ValueChangeListener listener;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
        if (txt != null) {
            txt.setText(value);
        }
    }

    public CustomComponent(Context context) {
        super(context);
        init(context);
    }

    public CustomComponent(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public CustomComponent(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs);
    }

    private void init(Context context) {

    }

    private void init(Context context, AttributeSet attrs) {
        View.inflate(context, R.layout.custom_component, this);
        txt = findViewById(R.id.txt_box);
        final CustomComponent self = this;
        textWatcher = new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                if (listener != null) {
                    listener.onValueChange(self, editable.toString());
                }
            }
        };
        txt.addTextChangedListener(textWatcher);
    }

    public void addListener(ValueChangeListener listener) {
        this.listener = listener;
    }

    public void removeListener(ValueChangeListener listener) {
        this.listener = null;
    }
}

public interface ValueChangeListener {
    public void onValueChange(CustomComponent view, String value);
}

我认为那篇文章中的“挂钩事件”部分完全超出了我的想象。我真的只需要一个简单的组件的 setter 和 getter,所以不能完全理解 BindingAdapter 中正在做什么。在所有这些中,我认为这是我根本没有得到的这条线:

ValueChangeListener oldListener =
            ListenerUtil.trackListener(view, newListener,
                    R.id.textWatcher);

演示:https ://github.com/indgov/data_binding

4

1 回答 1

2

抱歉,ListenerUtil 令人困惑。这仅在您的组件支持多个侦听器时才有用。在这种情况下,您不能只设置一个新的侦听器,您必须删除旧的侦听器并添加新的侦听器。ListenerUtil 帮助您跟踪旧的侦听器,以便将其删除。在您的情况下,可以简化:

@BindingAdapter(
        value = {"onValueChange", "valueAttrChanged"},
        requireAll = false
)
public static void setListeners(CustomComponent view,
                                final ValueChangeListener onValueChangeListener,
                                final InverseBindingListener inverseBindingListener) {
    ValueChangeListener newListener;
    if (inverseBindingListener == null) {
        newListener = onValueChangeListener;
    } else {
        newListener = new ValueChangeListener() {
            @Override
            public void onValueChange(CustomComponent view,
                                      String value) {
                if (onValueChangeListener != null) {
                    onValueChangeListener.onValueChange(view,
                            value);
                }
                inverseBindingListener.onChange();
            }
        };
    }

    view.setListener(newListener);
}

然后替换addListener()setListener()and 你不需要removeListener()因为你总是可以将监听器设置为null.

您看到的问题出在您的组件中:

public String getValue() {
    return value;
}

您将返回 setter 上次设置的值,而不是 EditText 中的值。要解决这个问题:

public String getValue() {
    return txt.getText().toString();
}
于 2017-09-08T20:33:22.207 回答