是否可以使用BindingAdapter直接将事件绑定到Observable字段?

时间:2016-02-28 17:13:34

标签: android android-databinding

我正在为android-support-design库提供的底页编写绑定适配器。我想要实现的是将状态更改事件绑定到可观察字段,从而完全避免事件处理程序的粘合代码。

public class BottomSheetBindingAdapter {

    @BindingAdapter("behavior_onStateChange")
    public static void bindBottomSheetStateChange(final View view, final ObservableInt state) {
        final BottomSheetBehavior<View> behavior = BottomSheetBehavior.from(view);
        if (behavior == null) throw new IllegalArgumentException(view + " has no BottomSheetBehavior");
        behavior.setBottomSheetCallback(new BottomSheetCallback() {

            @Override public void onStateChanged(@NonNull final View bottomSheet, final int new_state) {
                state.set(new_state);
            }

            @Override public void onSlide(@NonNull final View bottomSheet, final float slideOffset) {}
        });
    }
}

在布局XML中:

bind:behavior_onStateChange="@{apps.selection.bottom_sheet_state}"

其中&#34; bottom_sheet_state&#34;是ObservableInt的一个字段。

然后编译器发出警告:Cannot find the setter for attribute 'bind:behavior_onStateChange' with parameter type int.似乎数据绑定编译器在匹配BindingAdapter时总是将ObservableInt字段视为int。

如何实际编写BindingAdapter来绑定事件处理程序以更改Observable字段,而不在视图模型类中使用胶水代码?

1 个答案:

答案 0 :(得分:1)

您无法更改ObservableInt中的BindingAdapter值,并希望它会反映在视图模型中。你想要什么我 s双向绑定。由于没有提供开箱即用的bottomSheetState属性,我们需要通过创建InverseBindingAdapter来创建双向绑定。

@InverseBindingAdapter(
    attribute = "bottomSheetState",
    event = "android:bottomSheetStateAttrChanged"
)
fun getBottomSheetState(view: View): Int {
    return BottomSheetBehavior.from(view).state
}
@BindingAdapter(value = ["android:bottomSheetStateAttrChanged"], requireAll = false)
fun View.setBottomSheetStateListener(inverseBindingListener: InverseBindingListener) {
    val bottomSheetCallback = object : BottomSheetBehavior.BottomSheetCallback() {
        override fun onStateChanged(bottomSheet: View, @BottomSheetBehavior.State newState: Int) {
            inverseBindingListener.onChange()
        }

        override fun onSlide(bottomSheet: View, slideOffset: Float) {}
    }
    BottomSheetBehavior.from(this).addBottomSheetCallback(bottomSheetCallback)
}
顺便说一下,这是kotlin代码。在顶级的任何kt文件中添加此项。然后,您可以在xml中使用app:bottomSheetState="@={viewModel.bottomSheetState}",而bottomSheetStateObservableInt

现在,您可以在bottomSheetState上观察底部的状态变化。