是否可以使用 BindingAdapter 直接将事件绑定到 Observable 字段?
Is it possible to bind event to Observable field directly with BindingAdapter?
我正在为底部 sheet 编写绑定适配器,由 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 字段,而无需视图模型中的胶水代码class?
您不能更改 BindingAdapter
中的 ObservableInt
值并期望它反映在视图模型中。你想要的是我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)
}
顺便说一句,这是科特林代码。将此添加到顶层的任何 kt 文件中。然后你可以在 xml 中使用 like app:bottomSheetState="@={viewModel.bottomSheetState}"
而 bottomSheetState
是 ObservableInt
.
现在您可以在 bottomSheetState
上观察底部 sheet 的状态变化。
我正在为底部 sheet 编写绑定适配器,由 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 字段,而无需视图模型中的胶水代码class?
您不能更改 BindingAdapter
中的 ObservableInt
值并期望它反映在视图模型中。你想要的是我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)
}
顺便说一句,这是科特林代码。将此添加到顶层的任何 kt 文件中。然后你可以在 xml 中使用 like app:bottomSheetState="@={viewModel.bottomSheetState}"
而 bottomSheetState
是 ObservableInt
.
现在您可以在 bottomSheetState
上观察底部 sheet 的状态变化。