Обработка множественного выбора в Android RecyclerView - PullRequest
0 голосов
/ 28 марта 2019

Я использую onLongClickListener для элементов в статусе RecyclerView, выбранных / не выбранных, и меняю цвет фона элемента. Выбор работает отлично, но некоторые дополнительные элементы в списке также меняют цвет (хотя их состояние остается «невыбранным»). Я подозреваю, что проблема связана с повторным использованием видоискателя, но я не знаю, как это исправить. Я следовал за этим , чтобы реализовать множественный выбор, который мне абсолютно необходим в приложении.

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 ]

1 голос
/ 28 марта 2019

RecyclerView будет повторно использовать представления для заполнения данных.

Просто добавьте эту строку taskViewHolder.item_container.setBackgroundColor(taskItem.isSelected() ? Color.CYAN : Color.WHITE); к onBindViewHolder, чтобы исправить ее (при прокрутке будет установлен правильный цвет)

0 голосов
/ 28 марта 2019

Переопределите эти методы в своем классе Adapter следующим образом.

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

@Override
public int getItemViewType(int position) {
 return position;
}
0 голосов
/ 28 марта 2019

Добавьте эти два метода в утилиту для повторного просмотра

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

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