如何以编程方式更改现有图层列表的项目(ScaleDrawable)的颜色

时间:2014-10-21 16:32:44

标签: android android-drawable android-progressbar layer-list

我有一个现有的图层列表,用于自定义ProgressBar,如下所示:

style_progress_bar.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@android:id/background"
        android:drawable="#F6F3F1" />
    <item android:id="@android:id/secondaryProgress">
        <scale
            android:drawable="#DE0012"
            android:scaleWidth="100%" />
    </item>
    <item android:id="@android:id/progress">
        <scale
            android:drawable="#DE0012"
            android:scaleWidth="100%" />
    </item>
</layer-list>

此图层列表用于覆盖ProgressBar的progressDrawable属性,并且像魅力一样工作。

现在,我想使用相同的主干,但我想以编程方式更改第二个和第三个项目的颜色,因为进度颜色应该在很多情况下改变并且创建大量的xml文件是我不想要的不行,甚至都不是个好主意。

我设法阅读上面的文件并阅读了它的第二和第三项,但我找不到合适的解决方案来改变这些颜色2.除了颜色问题,一切都按预期工作。

LayerDrawable layers = (LayerDrawable) getResources().getDrawable(R.drawable.style_progress_bar);
int color = getResources().getColor(colorId); // This is the ID of the new color. I use it elsewhere so this should be 100% good

layers.getDrawable(1).setColorFilter(color, PorterDuff.Mode.MULTIPLY);
layers.getDrawable(2).setColorFilter(color, PorterDuff.Mode.MULTIPLY);

// I even called invalidate(); after all this. Nothing changed

我觉得我真的很接近把它包起来但是我卡住了。

有什么想法吗? 谢谢!

1 个答案:

答案 0 :(得分:1)

好的,我真的在这里领先,抱歉。

深入挖掘我意识到我可以读取所需的2个drawable作为ScaleDrawable对象,因为这是它们在xml文件中的设置方式,如scale。

每个缩放项目都有自己的drawables设置:

<scale 
    android:drawable="#DE0012" 
    android:scaleWidth="100%" />

所以我意识到,那些也可以以某种方式阅读。是的,它们可以被读作ColorDrawable对象。在我拥有2个ColorDrawable对象的时候,我能够简单地为这些设置颜色。 这是我做最后一切的最终代码:

private Drawable createDrawable(int colorId) {
    LayerDrawable layers = (LayerDrawable) getResources().getDrawable(R.drawable. style_progress_bar);
    int color = getResources().getColor(colorId);
    try {
        ScaleDrawable first = (ScaleDrawable) layers.getDrawable(1);
        ScaleDrawable second = (ScaleDrawable) layers.getDrawable(2);
        ColorDrawable secondaryColor = (ColorDrawable) first.getDrawable();
        secondaryColor.setColor(color);
        ColorDrawable primaryColor = (ColorDrawable) second.getDrawable();
        primaryColor.setColor(color);
    } catch (ClassCastException e) {
        e.printStackTrace();
    }
    return layers;
}

在此之后,我可以简单地调用上面的方法并动态更改颜色。

progressBar.setProgressDrawable(createDrawable(colorId));

谢谢,对此感到抱歉,但我想我会留下这个问题,以防有人在需要使用ScaleDrawable时遇到这种特殊情况。

请注意,在xml 图层列表的项目中使用 scale 以外的其他内容,会使progressView完全着色,而您不会获得所需的结果,例如具有不同的背景颜色和实际进度的另一种颜色。