0

我已经在几篇文章中看到了这种类型的答案,但由于某种原因,这似乎对我不起作用。这是我的代码:

public class ScheduleAdapter extends RecyclerView.Adapter<ScheduleAdapter.ScheduleViewHolder>
{
private Context context;
private ListitemScheduleBinding binding;
private Util util;
private List<TimeSlot> scheduleItems;
private ItemClickListener itemClickListener;
private int selectedPosition = RecyclerView.NO_POSITION;

public ScheduleAdapter(Context context, List<TimeSlot> scheduleItems)
{
    this.context = context;
    this.scheduleItems = scheduleItems;
    util = new Util();
}

@NonNull
@Override
public ScheduleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
    binding = ListitemScheduleBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
    return new ScheduleViewHolder(binding.getRoot());
}

@Override
public void onBindViewHolder(@NonNull ScheduleViewHolder holder, int position)
{
    if (selectedPosition == position)
    {
        binding.cardView.setCardBackgroundColor(Color.BLACK);
    }
    else
    {
        binding.cardView.setCardBackgroundColor(Color.GRAY);
    }

    binding.cardView.setOnClickListener(v -> {
        if(selectedPosition == position)
        {
            selectedPosition = RecyclerView.NO_POSITION;
            notifyDataSetChanged();
            return;
        }

        selectedPosition = position;
        notifyDataSetChanged();
    });

    TimeSlot scheduleItem = scheduleItems.get(position);

    String[] dateSplit = scheduleItem.getDate().split("-");
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.YEAR, Integer.parseInt(dateSplit[0]));
    calendar.set(Calendar.MONTH, (Integer.parseInt(dateSplit[1]) - 1));
    calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateSplit[2]));

    binding.day.setText(util.getDayNameFromInt(calendar.get(Calendar.DAY_OF_WEEK)));
    binding.date.setText(String.format(Locale.getDefault(), "%s %s", dateSplit[2], util.getMonthShortNameFromInt(calendar.get(Calendar.MONTH))));
    binding.slot.setText(scheduleItem.getTitle());
}

@Override
public int getItemCount()
{
    return scheduleItems.size();
}

public class ScheduleViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
    ScheduleViewHolder(@NonNull View itemView)
    {
        super(itemView);
        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View view)
    {
        if (itemClickListener != null)
        {
            itemClickListener.onItemClick(view, getAdapterPosition());
        }
    }
}

public void setClickListener(ItemClickListener clickListener)
{
    this.itemClickListener = clickListener;
}

public interface ItemClickListener
{
    void onItemClick(View view, int position);
}

}

可以看到,我已经在堆栈上实现了此处提到的答案以及有关此问题的各种其他问题。

但是,当我单击列表中的某个项目时,它要么没有突出显示,要么突出显示另一个项目而不是我单击的项目。有时,单击项目的内容会更改为列表中另一个项目的内容。

我究竟做错了什么?

4

2 回答 2

0

绑定对象必须在 ViewHolder 类中刷新。不要使用 binding.view,而是使用 holder.binding.view。在 ViewHolder 中声明绑定并在那里为其赋值。

这是工作更新的适配器:

public class ScheduleAdapter extends RecyclerView.Adapter<ScheduleAdapter.ScheduleViewHolder>
{
private Util util;
private List<TimeSlot> scheduleItems;
private ItemClickListener itemClickListener;
private int lastClickedPosition = RecyclerView.NO_POSITION;

public ScheduleAdapter(List<TimeSlot> scheduleItems)
{
    this.scheduleItems = scheduleItems;
    util = new Util();
}

@NonNull
@Override
public ScheduleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
{
    return new ScheduleViewHolder(ListitemScheduleBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
}

@Override
public void onBindViewHolder(@NonNull ScheduleViewHolder holder, int position)
{
    TimeSlot scheduleItem = scheduleItems.get(position);

    String[] dateSplit = scheduleItem.getDate().split("-");
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.YEAR, Integer.parseInt(dateSplit[0]));
    calendar.set(Calendar.MONTH, (Integer.parseInt(dateSplit[1]) - 1));
    calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateSplit[2]));

    holder.binding.day.setText(util.getDayNameFromInt(calendar.get(Calendar.DAY_OF_WEEK)));
    holder.binding.date.setText(String.format(Locale.getDefault(), "%s %s", dateSplit[2], util.getMonthShortNameFromInt(calendar.get(Calendar.MONTH))));
    holder.binding.slot.setText(scheduleItem.getTitle().replaceFirst(" ", "\n"));

    holder.itemView.setSelected(lastClickedPosition == position);
}

@Override
public int getItemCount()
{
    return scheduleItems.size();
}

public class ScheduleViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
    ListitemScheduleBinding binding;

    ScheduleViewHolder(@NonNull ListitemScheduleBinding binding)
    {
        super(binding.getRoot());
        this.binding = binding;
        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View view)
    {
        if (itemClickListener != null)
        {
            itemClickListener.onItemClick(view, getAdapterPosition());
        }

        notifyItemChanged(lastClickedPosition);
        lastClickedPosition = getLayoutPosition();
        notifyItemChanged(lastClickedPosition);
    }
}

public void setClickListener(ItemClickListener clickListener)
{
    this.itemClickListener = clickListener;
}

public interface ItemClickListener
{
    void onItemClick(View view, int position);
}

}

于 2020-07-03T08:42:45.827 回答
0

RecyclerView不像 ListView 那样处理项目选择或状态。相反,您必须在视图持有者中手动处理此问题。

在您的 `ViewItemHolder 构造函数中:

public ViewItemHolder(View holderItemView) {
        super(holderItemView);

        // Make this view clickable
        holderItemView.setClickable(true);

        // ...
    } 
于 2020-07-02T09:05:24.630 回答