首页 > 解决方案 > 自定义 SeekBar 侦听器数据绑定

问题描述

我正在尝试使用 Android 数据绑定在自定义 SeekBar ( https://github.com/warkiz/IndicatorSeekBar ) 上设置监听器。在标准 SeekBar 中,我以这种方式设置 onProgressChanged 侦听器:
片段的 XML:

<SeekBar
    ...
    android:onProgressChanged="@{viewModel::seekBarStopTracking}"
    ... 
/>

片段的 ViewModel:

public void seekBarStopTracking(SeekBar view, int progress, boolean fromUser) {
       
}

我正在尝试对 IndicatorSeekBar 做同样的事情,但是它有一些不同的侦听器:
来自 github 的示例:

seekBar.setOnSeekChangeListener(new OnSeekChangeListener() {
    @Override
    public void onSeeking(SeekParams seekParams) {
    }

    @Override
    public void onStartTrackingTouch(IndicatorSeekBar seekBar) {
    }

    @Override
    public void onStopTrackingTouch(IndicatorSeekBar seekBar) {
    }
});

XML:

<com.warkiz.widget.IndicatorSeekBar
    ...
    app:onSeeking="@{viewModel::seeking}"
    ...
/>

视图模型:

public void seeking(SeekParams params){
    
}

也试过:

public void seeking(IndicatorSeekBar seekBar, SeekParams params){
    
}

但结果是一样的:

[数据绑定] {"msg":"无法解析 viewModel::seeking 作为监听器。

我做错了什么?谢谢

标签: androiddata-bindingseekbar

解决方案


这是一个自定义视图,因此您需要编写自己的Binding Adapters。这是解决方案:

第一步:创建绑定类

IndicatorSeekBarBindingAdapter.java

public class IndicatorSeekBarBindingAdapter {

    @BindingAdapter(value = {"app:onSeeking", "app:onStartTrackingTouch",
            "app:onStopTrackingTouch"}, requireAll = false)
    public static void setOnSeekBarChangeListener(IndicatorSeekBar seekBar,
                                                  final OnSeeking seeking,
                                                  final OnStartTrackingTouch start,
                                                  final OnStopTrackingTouch stop) {
        if (seeking != null || start != null || stop != null) {
            seekBar.setOnSeekChangeListener(new OnSeekChangeListener() {
                @Override
                public void onSeeking(SeekParams seekParams) {
                    if (seeking != null) {
                        seeking.onSeeking(seekBar, seekParams);
                    }
                }

                @Override
                public void onStartTrackingTouch(IndicatorSeekBar seekBar) {
                    if (start != null) {
                        start.onStartTrackingTouch(seekBar);
                    }
                }

                @Override
                public void onStopTrackingTouch(IndicatorSeekBar seekBar) {
                    if (stop != null) {
                        stop.onStopTrackingTouch(seekBar);
                    }
                }
            });
        }
    }

    public interface OnSeeking {
        void onSeeking(IndicatorSeekBar seekBar, SeekParams seekParams);
    }

    public interface OnStartTrackingTouch {
        void onStartTrackingTouch(IndicatorSeekBar seekBar);
    }

    public interface OnStopTrackingTouch {
        void onStopTrackingTouch(IndicatorSeekBar seekBar);
    }
}

第 2 步:将以下代码添加到您的视图模型类中。

public class MyViewModel extends ViewModel {

    public void onSeeking(IndicatorSeekBar seekBar, SeekParams seekParams) {
        Log.i("TAG", "onSeeking: " + seekParams.progress);
    }

    public void onStartTrackingTouch(IndicatorSeekBar seekBar) {
        Log.i("TAG", "onStartTrackingTouch: " + seekBar.getProgress());
    }

    public void onStopTrackingTouch(IndicatorSeekBar seekBar) {
        Log.i("TAG", "onStopTrackingTouch: " + seekBar.getProgress());
    }
}

第 3 步:从布局 xml 文件中使用它

<com.warkiz.widget.IndicatorSeekBar
    android:id="@+id/seekBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:onSeeking="@{viewModel::onSeeking}"
    app:onStartTrackingTouch="@{viewModel::onStartTrackingTouch}"
    app:onStopTrackingTouch="@{viewModel::onStopTrackingTouch}" />

推荐阅读