RecyclerView中的选定项目在滚动时发生更改 [英] Selected items in RecyclerView change on scrolling
问题描述
我有一个RecyclerView,每个元素代表一个事件.我想让用户通过单击选择事件.选择后,事件和报告按钮将变为彩色:
I have a RecyclerView with each element representing an event. I want to let the user select events by clicking it. Once selected, the event(s) and a report button will be colored:
在执行点击之前的用户界面:点击此处.
UI before performing a click: click here.
UI执行点击后:点击此处.
这非常简单,据称有效;我为每个负责为该项着色的 ViewHolder
设置了一个 OnClickListener
,并在触发时触发了名为 onOccurrenceSelected
的拥有活动中的另一个事件,负责更改按钮的状态.
It's pretty simple and allegedly works; I set an OnClickListener
for each ViewHolder
which is responsible for coloring the item, and when fired it's triggering another event in the owning activity named onOccurrenceSelected
, which is responsible for changing the button's state.
但是,当滚动浏览RecyclerView的项目时,其他不相关的项目会被着色,就像它们的 OnClickListener
被触发(虽然不是)一样,并且向后滚动时,选定的事件被着色为未选中.发生这种情况时,不会触发应该为项目着色的唯一事件.
However, when scrolling through the RecyclerView's items, other irrelevant items are colored like their OnClickListener
was triggered (though it wasn't), and when scrolling back the selected event is colored as not selected. While this is happening, the only event that's supposed to color the items is not triggered.
对这种行为有解释吗?谢谢!
Any explanation for such behavior? Thanks!
这是适配器的一些相关代码:
private List<Occurrence> mDataSet;
private Activity activity;
public <OccurrencesActivity extends OnOccurrenceSelectedListener> OccurrencesAdapter(OccurrencesActivity occurrencesActivity, List<Occurrence> occurrences) {
this.activity = (android.app.Activity) occurrencesActivity;
mDataSet = occurrences;
}
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
Occurrence instance = mDataSet.get(position);
...
setOnClickListener(holder, instance);
}
private void setOnClickListener(final ViewHolder holder, final Occurrence occurrence) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!occurrence.isSelected()) {
holder.itemView.setBackgroundColor(App.getContext().getResources().getColor(R.color.turquoise));
holder.titleTextView.setTextColor(App.getContext().getResources().getColor(R.color.white));
holder.statusTextView.setTextColor(App.getContext().getResources().getColor(R.color.white));
holder.dateTextView.setTextColor(App.getContext().getResources().getColor(R.color.white));
holder.timeTextView.setTextColor(App.getContext().getResources().getColor(R.color.white));
} else {
holder.itemView.setBackgroundColor(App.getContext().getResources().getColor(R.color.white));
holder.titleTextView.setTextColor(App.getContext().getResources().getColor(R.color.turquoise));
holder.statusTextView.setTextColor(App.getContext().getResources().getColor(R.color.grey));
holder.dateTextView.setTextColor(App.getContext().getResources().getColor(R.color.grey));
holder.timeTextView.setTextColor(App.getContext().getResources().getColor(R.color.grey));
}
occurrence.setSelected(!occurrence.isSelected());
((OnOccurrenceSelectedListener)activity).onOccurrenceSelected(mDataSet);
}
});
}
推荐答案
Recyclerview总是在滚动时重新使用视图,因此您必须将选定的位置存储到临时arraylist中,然后将条件检查保持在onBindViewHolder中,以确保该特定位置是否已经存在于arraylist中或不?我更新了你的衣服.找到以下带有评论的更改
Recyclerview always resuse views while scrolling so you have to store selected positions into temporary arraylist and then keep condition check into onBindViewHolder that whether that particular position is already exists in arraylist or not? I updated your adaper. find the below changes with comment
private List<Occurrence> mDataSet;
private Activity activity;
//Added here temporary ArrayList
private ArrayList<String> mSelectedPosition = new ArrayList<String>;
public <OccurrencesActivity extends OnOccurrenceSelectedListener> OccurrencesAdapter(OccurrencesActivity occurrencesActivity, List<Occurrence> occurrences) {
this.activity = (android.app.Activity) occurrencesActivity;
mDataSet = occurrences;
}
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
//Set ViewTag
holder.itemView.setTag(position);
//Check everyposition during view binding process
if(mSelectedPosition.contains(String.valueOf(position))){
holder.itemView.setBackgroundColor(App.getContext().getResources().getColor(R.color.white));
holder.titleTextView.setTextColor(App.getContext().getResources().getColor(R.color.turquoise));
holder.statusTextView.setTextColor(App.getContext().getResources().getColor(R.color.grey));
holder.dateTextView.setTextColor(App.getContext().getResources().getColor(R.color.grey));
holder.timeTextView.setTextColor(App.getContext().getResources().getColor(R.color.grey));
}else{
holder.itemView.setBackgroundColor(App.getContext().getResources().getColor(R.color.white));
holder.titleTextView.setTextColor(App.getContext().getResources().getColor(R.color.turquoise));
holder.statusTextView.setTextColor(App.getContext().getResources().getColor(R.color.grey));
holder.dateTextView.setTextColor(App.getContext().getResources().getColor(R.color.grey));
holder.timeTextView.setTextColor(App.getContext().getResources().getColor(R.color.grey));
}
Occurrence instance = mDataSet.get(position);
...
setOnClickListener(holder, instance);
}
private void setOnClickListener(final ViewHolder holder, final Occurrence occurrence) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Get Position
int position = (int) view.getTag();
//Remove SelectedPosition if Already there
if(mSelectedPosition.contains(position))
mSelectedPosition.remove(String.valueOf(position));
else
mSelectedPosition.add(String.valueOf(position));
notifyDataSetChanged();
//Not sure about this lines
occurrence.setSelected(!occurrence.isSelected());
((OnOccurrenceSelectedListener)activity).onOccurrenceSelected(mDataSet);
}
});
}
这篇关于RecyclerView中的选定项目在滚动时发生更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!