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
并为不同的状态设置颜色,要么通过解析颜色资源直接设置颜色,
最近我在使用 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
并为不同的状态设置颜色,要么通过解析颜色资源直接设置颜色,