【问题标题】:Selected items in RecyclerView change on scrollingRecyclerView 中的选定项目在滚动时发生变化
【发布时间】:2016-09-27 12:12:56
【问题描述】:

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

执行点击前的 UI:click here

用户界面点击后:click here

这很简单,据称有效;我为每个 ViewHolder 设置了一个 OnClickListener,它负责为项目着色,并在触发时触发名为 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);
        }
    });
}

【问题讨论】:

  • 显示您的适配器代码
  • @SarthakMittal 添加。
  • 在您的适配器类中覆盖此方法 - @Override public int getItemViewType(int position) { return position; }

标签: java android android-recyclerview


【解决方案1】:

Recyclerview 总是在滚动时重用视图,因此您必须将选定的位置存储到临时数组列表中,然后在 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);
            }
        });
    }

【讨论】:

  • 如何获取视图在onClick中的位置?
  • @NeriaNachum :您可以通过将标签设置为 itemview 来获取它。我更新了代码。再看一遍!
  • 我是通过从OnBindViewHolder 传入的,它可以工作。谢谢!
【解决方案2】:

它是recyclerview 的默认行为。它将回收/重用当前未使用的视图。如果要保存有色或无色的状态。然后在每个位置的List&lt;Object&gt; 中保存一个参数。并根据onBindViewHolder 方法中的位置使用该位置来更改颜色。

【讨论】:

    【解决方案3】:

    尝试在适配器的onBindViewHolder 中为您的项目设置标签

    holder.yourItem.setTag(position);
    

    然后在onClickListener里面,把那个位置保存在shared Pref中就好了。如果它被选中,无论何时设置适配器,然后在设置值之前检查它是否基于共享首选项被选中。并执行相同的操作。

    public void onClick(View view) {
        if (!occurrence.isSelected()) {
            //save position in share pref.
        } 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多