You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 07:57:49