在Android RecyclerView中处理多重选择

时间:2019-03-28 12:32:11

标签: android android-recyclerview onclicklistener android-adapter

我使用onLongClickListener来选择/取消选择处于RecyclerView状态的项目,并更改项目背景颜色。选择效果很好,但列表下方的其他一些项目也会更改颜色(尽管它们的状态保持为“未选中”)。我的怀疑是问题是由于视图持有者被重用,但是我不知道如何解决。我遵循this来实现多项选择,这是我在应用程序中绝对需要的。

public class TasksPagedAdapter extends PagedListAdapter<Task, TaskViewHolder> {

private static DiffUtil.ItemCallback<Task> DIFF_CALLBACK = new DiffUtil.ItemCallback<Task>() {
    @Override
    public boolean areItemsTheSame(@NonNull Task task, @NonNull Task t1) {

        return task.getId() == t1.getId();
    }

    @Override
    public boolean areContentsTheSame(@NonNull Task task, @NonNull Task t1) {
        return task.equals(t1);
    }
};

private ItemClickListener itemClickListener;

protected TasksPagedAdapter(ItemClickListener itemClickListener) {
    super(DIFF_CALLBACK);

    setHasStableIds(true);
    this.itemClickListener = itemClickListener;
}

@NonNull
@Override
public TaskViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int position) {

    View itemRootView = LayoutInflater
            .from(parent.getContext())
            .inflate(R.layout.item_tarea, parent, false);

    return new TaskViewHolder(itemRootView);
}

@Override
public void onBindViewHolder(@NonNull TaskViewHolder taskViewHolder, int position) {

    Task taskItem = getItem(position);

    int importancia = taskItem.getImportancia();
    switch (importancia) {
        case 0:
            taskViewHolder.iv_importancia.setImageResource(R.drawable.icon_importancia_0);
            break;
        case 1:
            taskViewHolder.iv_importancia.setImageResource(R.drawable.icon_importancia_1);
            break;
        case 2:
            taskViewHolder.iv_importancia.setImageResource(R.drawable.icon_importancia_2);
            break;
        case 3:
            taskViewHolder.iv_importancia.setImageResource(R.drawable.icon_importancia_3);
            break;
        case 4:
            taskViewHolder.iv_importancia.setImageResource(R.drawable.icon_importancia_4);
            break;
        default:
            taskViewHolder.iv_importancia.setImageResource(R.drawable.icon_importancia_0);
            break;
    }
    taskViewHolder.tv_asunto.setText(taskItem.getAsunto());
    taskViewHolder.tv_fecha_creacion.setText(taskItem.getFechaCreacion());
    taskViewHolder.item_container.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            itemClickListener.onItemClick(position);
        }
    });
    taskViewHolder.item_container.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            itemClickListener.onItemLongClick(position);

            taskItem.setSelected(!taskItem.isSelected());
            taskViewHolder.item_container.setBackgroundColor(taskItem.isSelected() ? Color.CYAN : Color.WHITE);

            return true;
        }
    });
}

public Task getListItem(int position) {
    return getItem(position);
}

public List<Integer> getSelectedTasks() {
    List<Integer> selectedTasksIds = new ArrayList<>();
    for (Task task : getCurrentList().snapshot()) {
        if (task.isSelected()) {
            selectedTasksIds.add(task.getId());
        }
    }
    return selectedTasksIds;
}

@Override
public long getItemId(int position) {
    return position;
}

}

3 个答案:

答案 0 :(得分:1)

RecyclerView将重用视图来填充数据。

只需将此行taskViewHolder.item_container.setBackgroundColor(taskItem.isSelected() ? Color.CYAN : Color.WHITE);添加到onBindViewHolder即可修复(当您滚动时将设置正确的颜色)

答案 1 :(得分:0)

在recyclerview适配器中添加这两种方法

 override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    override fun getItemViewType(position: Int): Int {
        return position
    }

答案 2 :(得分:0)

像这样在Adapter类中覆盖这些方法。

@Override
public long getItemId(int position) {
 return position;
}

@Override
public int getItemViewType(int position) {
 return position;
}