CardView 在展开时改变颜色

CardView changes color when expanded

最近我在使用 CardView 时遇到了一个非常奇怪的行为。场景如下:我有一个使用 CardViews 作为项目的 RecyclerView。数据是动态的,从互联网上获取,就在 RecyclerView 被填充之前。 每个 CardView 都分配给 Job.java 的一个实例。作业有一个 isPending() - 布尔值,returns 为真或假(奇迹)。卡片的背景颜色(和文本)由 isPending()-boolean 确定,它是这样完成的

holder.cv.setCardBackgroundColor(jobs.get(position).isPending()?Color.parseColor("#FFDF72"):holder.cv.getCardBackgroundColor().getDefaultColor());

到现在为止,它就像一个魅力。 然后我想添加一个 onClickListener 来扩展点击的卡片然后调用 notifyItemChanged(position); 这也可以正常工作。让我们来看看奇怪的行为。
当我展开一张白卡(未挂起)并关闭它时,一切正常。当我对黄牌(待定)做同样的事情时,一切都很好。 BUT 选择黄色卡片后,每当我打开一张白色卡片时,它会变成黄色,当展开时它会变黄,当它再次缩小时又会变回白色。 我完全不知道它是什么,因为我尝试调试并且在卡片设置颜色时,布尔值“isPending()”始终是正确的。

CardView 的 xml-代码:

<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:foreground="?android:attr/selectableItemBackground"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/cv"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    android:orientation="vertical"
    app:cardCornerRadius="2dp"
    app:cardElevation="6dp"
    android:clickable="true"
    android:focusable="true">

RVAdapter 的 onBindViewHolder 方法:

if(jobs.get(position).isPending()) { //the mentioned method expanded due to debug reasons
            System.out.println("hsdajdshakl");
            holder.cv.setCardBackgroundColor(Color.parseColor("#FFDF72"));
        } else holder.cv.setCardBackgroundColor(holder.cv.getCardBackgroundColor().getDefaultColor());
// ... irrelevant code
holder.cv.findViewById(R.id.job_add).setBackgroundColor(holder.cv.getCardBackgroundColor().getDefaultColor());
        holder.cv.findViewById(R.id.job_decline).setBackgroundColor(jobs.get(position).isPending()?Color.parseColor("#FFDF72"):holder.cv.getCardBackgroundColor().getDefaultColor());
        holder.cv.findViewById(R.id.job_personen).setBackgroundColor(jobs.get(position).isPending()?Color.parseColor("#FFDF72"):holder.cv.getCardBackgroundColor().getDefaultColor());

holder.itemView.setActivated(isExpanded);

        holder.itemView.setOnClickListener(v -> {
            mExpandedPosition = isExpanded?-1:position;
            //notifyItemChanged(previousExpandedPosition);
            //jobs.get(position).setPending(jobs.get(position).isPending()); for testing
            notifyItemChanged(position);
        });
holder.cv.findViewById(R.id.job_decline).setBackgroundColor(jobs.get(position).isPending()?Color.parseColor("#FFDF72"):holder.cv.getCardBackgroundColor().getDefaultColor());
    holder.cv.findViewById(R.id.job_personen).setBackgroundColor(jobs.get(position).isPending()?Color.parseColor("#FFDF72"):holder.cv.getCardBackgroundColor().getDefaultColor());

cv.getCardBackgroundColor() 将 return 一个 ColorStateList,因为您没有使用状态列表并且没有在 XML 或代码中指定任何状态列表,getDefaultColor() 颜色将 return 与 cardBackgroundColor.

相同的颜色

recyclerview 的诀窍在于它可能会或可能不会对特定位置使用相同的视图,假设有 10 个项目,那么对于第 6 个项目,它可能会使用用于第 3 项,假设您的第 3 项是黄色,那么对于第 6 项,它将得到 cv.getCardBackgroundColor(),调用 getDefaultColor() 将 return 变为黄色,原因在上面已解释。

解决方案是,要么指定ColorStateList并为不同的状态设置颜色,要么通过解析颜色资源直接设置颜色,