Android Adapter中getDrawable()对比Drawable不相等问题求助
为什么两个Drawable对比总是不相等?
这个问题我之前做Android开发时也踩过坑,核心原因和解决办法如下:
问题根源
每次调用getResources().getDrawable()或者ContextCompat.getDrawable()时,系统都会创建一个全新的Drawable实例——哪怕你传入的是同一个资源ID。这就意味着:
addToFavouriteImageView.getDrawable()是当前ImageView持有的一个Drawable对象context.getResources().getDrawable(R.drawable.ic_favorite_add)是刚生成的另一个全新的Drawable对象
用==对比的是对象的引用地址,两个不同的实例引用肯定不相等,所以你的判断条件永远不会成立。
推荐解决方案:用数据状态跟踪(最可靠)
不要通过Drawable对象来判断状态,而是给你的Recipe数据模型添加一个布尔字段(比如isFavourite),用数据来驱动UI的变化,这也是Android开发中更规范的做法。
步骤1:修改Recipe数据类
给你的Recipe类添加收藏状态的字段:
public class Recipe { // 原有字段:recipeName、description等 private boolean isFavourite; public boolean isFavourite() { return isFavourite; } public void setFavourite(boolean favourite) { isFavourite = favourite; } }
步骤2:更新ViewHolder的点击逻辑
在点击事件中,直接操作数据的状态,再根据状态设置对应的Drawable:
addToFavouriteImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (onFavouriteButtonClickListener != null) { int position = getAdapterPosition(); if (position != RecyclerView.NO_POSITION) { // 获取当前位置的Recipe对象(这里需要你能拿到Adapter的数据集,比如recipeList) Recipe currentRecipe = recipeList.get(position); // 切换收藏状态 boolean newFavState = !currentRecipe.isFavourite(); currentRecipe.setFavourite(newFavState); // 根据新状态设置图标 if (newFavState) { addToFavouriteImageView.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_favorite)); Toast.makeText(context, "已添加至收藏", Toast.LENGTH_SHORT).show(); } else { addToFavouriteImageView.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_favorite_add)); } // 通知适配器更新当前item(可选,确保状态一致) notifyItemChanged(position); onFavouriteButtonClickListener.addToFavourite(position); } } } });
备选方案:对比Drawable的ConstantState(不推荐,但应急可用)
如果你一定要对比Drawable对象,可以通过getConstantState()来判断——同一个资源ID的Drawable,它们的ConstantState是共享的,所以可以用它来做相等判断:
addToFavouriteImageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (onFavouriteButtonClickListener != null) { int position = getAdapterPosition(); if (position != RecyclerView.NO_POSITION) { Drawable currentDrawable = addToFavouriteImageView.getDrawable(); Drawable targetDrawable = ContextCompat.getDrawable(context, R.drawable.ic_favorite_add); // 一定要先做非空判断,避免空指针 boolean isCurrentAddState = false; if (currentDrawable != null && targetDrawable != null) { isCurrentAddState = currentDrawable.getConstantState().equals(targetDrawable.getConstantState()); } if (isCurrentAddState) { addToFavouriteImageView.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_favorite)); Toast.makeText(context, "clicked", Toast.LENGTH_SHORT).show(); } else { addToFavouriteImageView.setImageDrawable(targetDrawable); } onFavouriteButtonClickListener.addToFavourite(position); } } } });
为什么不推荐这个方案?
因为Drawable的状态可能会随着系统主题、配置变化(比如横竖屏切换、夜间模式切换)而改变,直接依赖Drawable对象判断状态很容易出现逻辑错误,而用数据跟踪状态的方式更稳定、更符合Android的设计思想。
内容的提问来源于stack exchange,提问作者user13286210
相关产品推荐
相关产品推荐

