gpt4 book ai didi

android - 如何为 material.Slider View 创建绑定(bind)适配器?

转载 作者:行者123 更新时间:2023-12-02 12:09:31 28 4
gpt4 key购买 nike

我的目标是 2 路数据绑定(bind) Material 。从我的 View 模型到 MutableLiveData 的 slider View :

   <com.google.android.material.slider.Slider
...
android:value="@={viewmodel.fps}"
...
/>

当然,它不起作用,因为 androidx.databinding 库中没有 Slider 的数据绑定(bind)适配器
[databinding] Cannot find a getter for <com.google.android.material.slider.Slider android:value> that accepts parameter type <java.lang.Integer>. If a binding adapter provides the getter, check that the adapter is annotated correctly and that the parameter type matches.

但是,他们有一个用于 SeekBar: /androidx/databinding/adapters/SeekBarBindingAdapter.java

据我了解,2 向数据绑定(bind)应该只适用于“progress”属性,而 1 向数据绑定(bind)需要两个属性:“onChanged”和“progress”

我尝试为 Slider 调整 SeekBarBindingAdapter:
    @InverseBindingMethods({
@InverseBindingMethod(type = Slider.class, attribute = "android:value"),
})
public class SliderBindingAdapter {
@BindingAdapter("android:value")
public static void setValue(Slider view, int value) {
if (value != view.getValue()) {
view.setValue(value);
}
}

@BindingAdapter(value = {"android:valueAttrChanged", "android:onValueChange"}, requireAll = false)
public static void setOnSliderChangeListener(Slider view, final Slider.OnChangeListener valChanged, final InverseBindingListener attrChanged) {
if (valChanged == null)
view.addOnChangeListener(null);
else
view.addOnChangeListener((slider, value, fromUser) -> {
if (valChanged != null)
valChanged.onValueChange(slider, value, fromUser);
});


if (attrChanged != null) {
attrChanged.onChange();
}
}

@Override
public void onValueChange(@NonNull Slider slider, float value, boolean fromUser) {

}

它不是在 build :
Could not find event android:valueAttrChanged on View type Slider

但是如果我只使用它为什么会寻找 valueAttrChanged
android:value="@={viewmodel.fps}"

?

如果在 Slider 类中看不到 valueAttrChanged,如何找到要添加到 BindingAdapter 的正确属性?

最佳答案

来看看SeekBarBindingAdapter's setOnSeekBarChangeListener()方法。它添加了四个不同的属性:{"android:onStartTrackingTouch", "android:onStopTrackingTouch", "android:onProgressChanged", "android:progressAttrChanged"}但只有最后一个用于双向数据绑定(bind)。

但是为什么有四个属性呢?如果你看SeekBar类,它有 setOnSeekBarChangeListener()允许您设置和删除监听器的方法。问题是 SeekBar 只能有一个监听器,而 listener提供不同的回调:onProgressChanged , onStartTrackingTouchonStopTrackingTouch .
SeekBarBindingAdapter注册自己的监听器,这意味着没有人可以在不删除现有监听器的情况下注册另一个监听器。这就是为什么 SeekBarBindingAdapter提供onStartTrackingTouch , onStopTrackingTouchonProgressChanged属性,因此您无需注册自己的 OnSeekBarChangeListener 即可收听这些事件.

实际上是Slider适配器可以比 SeekBarBindingAdapter 简单得多,因为 Slider 允许您使用 addOnChangeListener() 添加和删除监听器和 removeOnChangeListener() .因此双向数据绑定(bind)适配器可以注册自己的监听器,其他任何人都可以注册其他监听器而无需删除以前的监听器。

它允许我们定义一个非常简洁的适配器。我创建了一个 kotlin 示例,希望您可以将其翻译为 java:

@InverseBindingAdapter(attribute = "android:value")
fun getSliderValue(slider: Slider) = slider.value

@BindingAdapter("android:valueAttrChanged")
fun setSliderListeners(slider: Slider, attrChange: InverseBindingListener) {
slider.addOnChangeListener { _, _, _ ->
attrChange.onChange()
}
}

和布局:

...
<com.google.android.material.slider.Slider
...
android:value="@={model.count}" />
...

您可以找到完整的资源 here .

关于android - 如何为 material.Slider View 创建绑定(bind)适配器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62026687/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com