ListView:动态更改兄弟姐妹的数据

ListView: change siblings' data dynamically

我有一个 ListView,每个项目都包含一个 SeekBar

我想实现的是当其中一个SeekBar缓慢滑动时,其余SeekBar同时优雅滑动(这就是我要的事件一项对其余列表项产生影响)。

我试图将所有视图存储在适配器内的视图数组中,但我遇到了意外和不可预测的行为(我猜这与 ListView 在内部管理子项的方式有关)。

关于如何正确完成此操作的任何提示?

非常感谢!

我会使用 RxJava 解决问题。

基本上,您有一个数据流(Seekbar 的当前位置)并且有任意数量的订阅者(每行每个 Seekbar)。

您需要某种 Observable,它具有以下特征:

  1. 您可以为该值设置一个值Observable
  2. 订阅后您可以收到之前发送的值

事实证明 BehaviorSubject 是您需要的那个。

因此,声明了 BehaviorSubject 这是:

BehaviorSubject<Integer> subject = BehaviorSubject.createDefault(0); // default value is 0

现在任何时候任何 Seekbar 的值改变只需执行 subject.onNext(currentPosition).

视图一显示在屏幕上 - 订阅流:

Disposable d = subject.subscribe(new Consumer<Integer>() {
    @Override
    public void accept(Integer integer) throws Exception {
        seekbar.setProgress(integer);
    }
)

回收视图时 - 从 Disposable:

中处理
d.dispose();

您可以使用 RxJava 或 event bus 等花哨的东西来完成此操作,或者无需外部依赖项:

class MyObjAdapter extends RecyclerView.Adapter<MyObjAdapter.MyObjViewHolder> {

    class MyObjViewHolder extends RecyclerView.ViewHolder {
        SeekBar bar;

        MyObjViewHolder(View itemView, SeekBar.OnSeekBarChangeListener listener) {
            super(itemView);
            bar = itemView.findViewById(R.id.bar);
            bar.setOnSeekBarChangeListener(listener);
        }

    }

    private LinearLayoutManager layoutManager;
    private int value = 0;
    private SeekBar.OnSeekBarChangeListener listener = new SeekBar.OnSeekBarChangeListener() {

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            if (fromUser) {
                value = progress;
                int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();
                notifyItemRangeChanged(firstVisiblePosition,
                        layoutManager.findLastVisibleItemPosition() - firstVisiblePosition + 1);
            }
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
        }

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


    public MyObjAdapter(LinearLayoutManager layoutManager) {
        this.layoutManager = layoutManager;
    }

    @Override
    public MyObjViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item, parent, false);

        return new MyObjViewHolder(view, listener);
    }

    @Override
    public void onBindViewHolder(MyObjViewHolder holder, int position) {
        holder.bar.setProgress(value);
    }

    @Override
    public int getItemCount() {
        return 100;
    }
}