4

我正在为 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}"

其中“bottom_sheet_state”是 ObservableInt 的一个字段。

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

我如何才能真正编写一个 BindingAdapter 来绑定事件处理程序以更改 Observable 字段,而无需视图模型类中的胶水代码?

4

1 回答 1

1

您不能更改ObservableIntBindingAdapter并期望它反映在视图模型中。你想要的是双向绑定。由于没有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 文件中。然后你可以app:bottomSheetState="@={viewModel.bottomSheetState}"在 xml 中使用 like 而bottomSheetStateis ObservableInt

现在您可以观察bottomSheetState底部表格中的状态变化。

于 2018-02-08T19:58:00.760 回答