更改NinePatchDrawable资源颜色

时间:2014-12-04 20:23:42

标签: android xml android-layout

我正在尝试设置Spinner元素的样式。我使用layer-list创建了资源。我在那里使用标准库资源@ drawable / abc_spinner_mtrl_am_alpha。这是一个箭头,它总是显示白色。在Android的api版本21中,在微调器中你可以设置属性android:backgroundTint,但我不知道如何在早期版本中执行此操作。

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:bottom="4dp"
        android:left="4dp"
        android:right="4dp"
        android:top="4dp" >

        <shape android:shape="rectangle">
            <stroke
                android:color="#999"
                android:width="1dp" />
            <corners android:radius="2dip" />
            <solid android:color="@android:color/transparent"/>
        </shape>

    </item>

    <item android:id="@+id/notPressedSpinner"
        android:drawable="@drawable/abc_spinner_mtrl_am_alpha"
        android:right="4dp" />
</layer-list>

我尝试使用setColorFilter以编程方式更改资源,但它不起作用。

    Drawable abcSpinnerMtrlAmAlpha = mContext.getResources()
            .getDrawable(R.drawable.abc_spinner_mtrl_am_alpha);
    Drawable abcSpinnerMtrlAmAlpha2 = mContext.getResources()
            .getDrawable(R.drawable.abc_spinner_mtrl_am_alpha);

    abcSpinnerMtrlAmAlpha.setColorFilter(mContext.getResources().getColor(R.color.gray_color),
            PorterDuff.Mode.SRC_ATOP);
    abcSpinnerMtrlAmAlpha2.setColorFilter(mContext.getResources().getColor(R.color.green),
            PorterDuff.Mode.SRC_ATOP);

    LayerDrawable x = ((LayerDrawable)mContext.getResources().getDrawable(R.drawable.x));
    LayerDrawable y = ((LayerDrawable)mContext.getResources().getDrawable(R.drawable.y));

    x.setDrawableByLayerId(R.id.notPressedSpinner, abcSpinnerMtrlAmAlpha);
    y.setDrawableByLayerId(R.id.notPressedSpinner, abcSpinnerMtrlAmAlpha2);

2 个答案:

答案 0 :(得分:3)

我的解决方案

public class StateListDrawableWithTint extends StateListDrawable {
    private ColorStateList mColorStateList;
    private PorterDuff.Mode mFilterMode;

    public StateListDrawableWithTint(Drawable drawable, ColorStateList colorStateList) {
        this(drawable, colorStateList, PorterDuff.Mode.MULTIPLY);
    }

    public StateListDrawableWithTint(Drawable drawable, ColorStateList colorStateList, PorterDuff.Mode filterMode) {
        super();

        mColorStateList = colorStateList;
        mFilterMode = filterMode;

        addState(new int[]{}, drawable);
    }

    @Override
    protected boolean onStateChange(int[] states) {
        if (mColorStateList != null) {
            int stateColor = mColorStateList.getColorForState(states, Color.TRANSPARENT);

            super.setColorFilter(stateColor, mFilterMode);
        }

        return super.onStateChange(states);
    }
}

使用:

spinner.setBackgroundDrawable(new StateListDrawableWithTint(
                getResources().getDrawable(R.drawable.sum_currency_spinner),
                getResources().getColorStateList(R.color.sum_currency_spinner),
                PorterDuff.Mode.SRC_ATOP));

绘制:              

        <shape android:shape="rectangle">
            <stroke
                android:color="#999"
                android:width="1.5dp" />
            <corners android:radius="2dip" />
            <solid android:color="@android:color/transparent"/>
        </shape>

    </item>

    <item android:id="@+id/notPressedSpinner"
        android:drawable="@drawable/abc_spinner_mtrl_am_alpha"
        android:right="4dp" />
</layer-list>

颜色状态:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- disabled state -->
    <item android:state_enabled="false" android:color="@color/light_green"/>
    <!-- pressed state -->
    <item android:state_enabled="true" android:state_window_focused="true" android:state_pressed="true" android:color="@color/light_green" />
    <!-- unselected state -->
    <item android:state_enabled="true" android:state_window_focused="true" android:color="@color/gray_color" />
    <!-- dropdown list state -->
    <item android:state_enabled="true" android:state_focused="true" android:color="@color/light_green" />
    <!-- default -->
    <item android:color="@color/light_green" />
</selector>

答案 1 :(得分:0)

private static final int[] FROM_COLOR = new int[]{49, 179, 110};
private static final int THRESHOLD = 3;

public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.test_colors);

ImageView iv = (ImageView) findViewById(R.id.img);
Drawable d = getResources().getDrawable(RES);
iv.setImageDrawable(adjust(d));
}

private Drawable adjust(Drawable d)
{
int to = Color.RED;

//Need to copy to ensure that the bitmap is mutable.
Bitmap src = ((BitmapDrawable) d).getBitmap();
Bitmap bitmap = src.copy(Bitmap.Config.ARGB_8888, true);
for(int x = 0;x < bitmap.getWidth();x++)
    for(int y = 0;y < bitmap.getHeight();y++)
        if(match(bitmap.getPixel(x, y))) 
            bitmap.setPixel(x, y, to);

return new BitmapDrawable(bitmap);
}

private boolean match(int pixel)
{
//There may be a better way to match, but I wanted to do a comparison ignoring
//transparency, so I couldn't just do a direct integer compare.
return Math.abs(Color.red(pixel) - FROM_COLOR[0]) < THRESHOLD &&
    Math.abs(Color.green(pixel) - FROM_COLOR[1]) < THRESHOLD &&
    Math.abs(Color.blue(pixel) - FROM_COLOR[2]) < THRESHOLD;
}