2016-02-28 118 views
3

我正在为android-support-design库提供的底部纸张写一个绑定适配器。我试图实现的是将状态更改事件绑定到可观察字段,从而完全避免事件处理程序的胶水代码。是否可以使用BindingAdapter直接将事件绑定到Observable字段?

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?

+0

如果你只需要改变你的观察到由一个int(仅在自定义绑定方法),并remplace了'state.set(NEW_STATE)''由国家= new_state',模型的束缚ObservableInt属性将被更新时, “onStateChanged”处理程序将被调用。 –

+0

@PaulDS这怎么可能?原始类型中的方法参数是“按值传递”。 'state = new_state'只会在方法范围内改变参数'state'的值。 –

+1

确实,你是对的。我在我的应用程序中找到的解决方案是创建我自己的自定义可观察(我需要它为其他事情,而不仅仅是这种情况)。你可以在这里找到我的例子:https://github.com/Paul-DS/SimpleFTP/blob/master/app/src/main/java/com/paulds/simpleftp/presentation/binders/FormBindings.java但我不”不知道这是否是最好的解决方案。 –

回答

1

您不能更改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) 
} 

顺便说一句,这是kotlin代码。将其添加到顶层的任何kt文件中。然后你就可以在XML使用像app:bottomSheetState="@={viewModel.bottomSheetState}"bottomSheetStateObservableInt。现在

你可以bottomSheetState观察在底纸的状态变化。

相关问题