How to customize custom drawable defined in XML at runtime?

android, android-attributes, android-drawable, android-layout

Solution

Like this:

InsetDrawable drawable = (InsetDrawable) myButton.getBackground();
GradientDrawable shape = (GradientDrawable) drawable.getDrawable();
shape.setColor(Color.BLUE);

I made a custom, multi-layered drawable to act as the background for a button.

This assumes `myButton` is the button which you refer to above and has been defined with

android:background="@drawable/custom_button"

EDIT

For an API level 1 way to do this:

Make a `custom_shape.xml` drawable:

<shape android:shape="rectangle">
    <corners android:radius="@dimen/control_corner_material" />
    <solid android:color="?attr/colorButtonNormal" />
    <padding android:left="@dimen/button_padding_horizontal_material"
        android:top="@dimen/button_padding_vertical_material"
        android:right="@dimen/button_padding_horizontal_material"
        android:bottom="@dimen/button_padding_vertical_material" />
</shape>

Write a method to change the colour of this drawable and put an inset around it:

private void changeColor() {
    // Get shape from XML
    GradientDrawable shape = (GradientDrawable) getResources().getDrawable(R.drawable.custom_shape);
    shape.setColor(Color.BLUE);

    // Programmatically create Inset
    InsetDrawable drawable =  new InsetDrawable(shape,
            getResources().getDimensionPixelSize(R.dimen.button_inset_horizontal_material),
            getResources().getDimensionPixelSize(R.dimen.button_inset_vertical_material),
            getResources().getDimensionPixelSize(R.dimen.button_inset_horizontal_material),
            getResources().getDimensionPixelSize(R.dimen.button_inset_vertical_material));

    // Apply to button
    myButton.setBackground(drawable);
}

Problem

I made a custom, multi-layered drawable to act as the background for a button. Sometimes, I want part of this drawable layer to be blue. Sometimes I want it to be green. Point is, it's a variable, and I want it to be definable in the associated custom view XML. Is this possible? How do I write a drawable in XML whose value I can determine at runtime? custom_button.xml ``` <?xml version="1.0" encoding="utf-8"?> <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="@dimen/button_inset_horizontal_material" android:insetTop="@dimen/button_inset_vertical_material" android:insetRight="@dimen/button_inset_horizontal_material" android:insetBottom="@dimen/button_inset_vertical_material"> <shape android:shape="rectangle"> <corners android:radius="@dimen/control_corner_material" /> <solid android:color="?attr/colorButtonNormal" /> <padding android:left="@dimen/button_padding_horizontal_material" android:top="@dimen/button_padding_vertical_material" android:right="@dimen/button_padding_horizontal_material" android:bottom="@dimen/button_padding_vertical_material" /> </shape> </inset> ``` The line `<solid android:color="?attr/colorButtonNormal" />` is what I want to set at runtime. I have my custom view for this class already receiving the color value I want to use here - how do I apply it to the XML of this drawable?

Original source

Related problems