可绘制着色代码适用于矢量但不适用于PNG

时间:2016-09-20 16:02:06

标签: android android-support-library android-drawable tint android-vectordrawable

所以我遇到了一个奇怪的问题......我已经制作了一些代码来为Drawable着色,它正在处理Vector资产的所有Android版本,但不适用于常规的PNG资产。代码如下:

public class TintHelper {

    private Context mContext;

    public TintHelper(Context context) {
        mContext = context;
    }

    public Drawable getTintedDrawableFromResource(int resourceID, ColorStateList colorStateList) {
        Drawable original = AppCompatDrawableManager.get().getDrawable(mContext, resourceID);
        return performTintOnDrawable(original, colorStateList);
    }

    private Drawable performTintOnDrawable(Drawable drawable, ColorStateList colorStateList) {
        Drawable tinted = DrawableCompat.wrap(drawable);
        DrawableCompat.setTintList(tinted, colorStateList);
        return tinted;
    }
}

当我指定矢量资源的资源ID时,代码完美运行并且按下时图像会着色,但是当我使用常规PNG时,按下图标时不会应用色调。如果有人对此为何不起作用有任何想法,请发布可能支持这两种资产类型的替代方法。

提前致谢!

2 个答案:

答案 0 :(得分:0)

在我的环境中,它适用于PNG。

设置如下:

int resourceID = R.drawable.ic_launcher;
TintHelper tintHelper = new TintHelper(this);
Drawable drawable = tintHelper.getTintedDrawableFromResource(resourceID,
        ContextCompat.getColorStateList(this, R.color.colors));

ImageView imageView = (ImageView) findViewById(R.id.image);
imageView.setImageDrawable(drawable);
colorsp就像这样:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true" android:color="@android:color/holo_red_dark"/>
    <item android:state_selected="true" android:color="@android:color/holo_red_dark"/>
    <item android:state_pressed="true" android:color="@android:color/holo_red_dark"/>
    <item android:color="@android:color/white"/>
</selector>

答案 1 :(得分:0)

我发现了问题。从本质上讲,DrawableCompat.setTintList()在Android 21及更高版本上无法正常运行。这是因为当状态发生变化时,它们的实现没有调用invalidate()。有关详细信息,请参阅此bug report

要使这个着色代码适用于所有平台和所有资源类型,我需要创建一个自定义ImageView类,如下所示:

public class StyleableImageView extends AppCompatImageView {

    public StyleableImageView(Context context) {
        super(context);
    }

    public StyleableImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public StyleableImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    // This is the function to override...
    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();
        invalidate();    // THE IMPORTANT LINE
    }
}

希望这可以帮助那些不得不处理类似情况的人。