ListView:动态更改兄弟姐妹的数据
ListView: change siblings' data dynamically
我有一个 ListView
,每个项目都包含一个 SeekBar
。
我想实现的是当其中一个SeekBar
缓慢滑动时,其余SeekBar
同时优雅滑动(这就是我要的事件一项对其余列表项产生影响)。
我试图将所有视图存储在适配器内的视图数组中,但我遇到了意外和不可预测的行为(我猜这与 ListView 在内部管理子项的方式有关)。
关于如何正确完成此操作的任何提示?
非常感谢!
我会使用 RxJava 解决问题。
基本上,您有一个数据流(Seekbar
的当前位置)并且有任意数量的订阅者(每行每个 Seekbar
)。
您需要某种 Observable
,它具有以下特征:
- 您可以为该值设置一个值
Observable
- 订阅后您可以收到之前发送的值
事实证明 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;
}
}
我有一个 ListView
,每个项目都包含一个 SeekBar
。
我想实现的是当其中一个SeekBar
缓慢滑动时,其余SeekBar
同时优雅滑动(这就是我要的事件一项对其余列表项产生影响)。
我试图将所有视图存储在适配器内的视图数组中,但我遇到了意外和不可预测的行为(我猜这与 ListView 在内部管理子项的方式有关)。
关于如何正确完成此操作的任何提示?
非常感谢!
我会使用 RxJava 解决问题。
基本上,您有一个数据流(Seekbar
的当前位置)并且有任意数量的订阅者(每行每个 Seekbar
)。
您需要某种 Observable
,它具有以下特征:
- 您可以为该值设置一个值
Observable
- 订阅后您可以收到之前发送的值
事实证明 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;
}
}