java - RecyclerView 中的选定项目在滚动时发生变化

标签 java android android-recyclerview

我有一个 RecyclerView,其中每个元素代表一个事件。我想让用户通过单击来选择事件。选择后,事件和报告按钮将被着色:

执行单击之前的 UI:click here .

用户界面执行点击后:click here .

这非常简单并且据称有效;我为每个 ViewHolder 设置了一个 OnClickListener ,它负责为项目着色,当触发时,它会触发拥有 Activity 中名为 onOccurrenceSelected 的另一个事件,它负责更改按钮的状态。

但是,当滚动 RecyclerView 的项目时,其他不相关的项目会被着色,就像它们的 OnClickListener 被触发一样(尽管没有触发),而当向后滚动时,所选事件会被着色为未选中。当发生这种情况时,不会触发唯一应该为项目着色的事件。

对这种行为有什么解释吗?谢谢!

编辑:以下是适配器中的一些相关代码:

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 在滚动时总是重复使用 View ,因此您必须将选定的位置存储到临时数组列表中,然后对 onBindViewHolder 进行条件检查,确定该特定位置是否已存在于数组列表中?我更新了你的适配器。找到以下带有注释的更改

    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);
            }
        });
    }

关于java - RecyclerView 中的选定项目在滚动时发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39724352/

相关文章:

java - springboot + thymeleaf 在html表格中显示数据库内容

java - 在最大等待时间后,c3p0 非 Activity 连接不会从连接池中剔除

android - 使用 Smack Api for Android 发送和接收消息

java - 抽屉导航中的操作与 fragment 更改

java - Android - 从其他 Activity 中的 AsyncTask 调用时,ListFragment 中的上下文不起作用

java - 将逗号分隔的列表粘贴到 EditText 中并存储在 SQLite TABLE 的多行中

java - 如何在暂停主执行而不是 UI 的同时解析 xml 文件

android - 当 recyclerview 放置在 scrollview/nestedScrollView 中时,scrollToPosition 方法不起作用

android - RecyclerView 适配器中的 onClickListener?

java - 创建自定义 RecyclerView 项目分隔符时出现空类