如何在运行时自定义在XML中定义的自定义可绘制对象?

3
我创建了一个自定义的多层可绘制对象,用作按钮的背景。有时候,我想让这个可绘制对象的一部分为蓝色,有时候我想把它变成绿色。关键是,它是一个变量,并且我希望在相应的自定义视图XML中定义它。
这是否可能?我如何编写一个可在运行时确定值的XML可绘制对象? 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>

这行代码 <solid android:color="?attr/colorButtonNormal" /> 是我想在运行时设置的。我已经有了这个类的自定义视图,已经接收到了我想要在此处使用的颜色值 - 我该如何将其应用于此可绘制对象的XML中?


不知道是否有一种方法可以在运行时以编程方式修改自定义逻辑。您可能需要创建两个custom_button.xml文件,并在需要其中一个时适当选择它们。 - Jay Snayder
@JaySnayder 我实际上正在尝试创建一个库,用于自定义按钮视图,使我能够轻松修改在此可绘制中使用的值。 - ZakTaccardi
将形状提取为可绘制对象,然后您可以动态更改其颜色:https://dev59.com/nGw05IYBdhLWcg3wkik- - Javi Mollá
1个回答

4
就像这样:
InsetDrawable drawable = (InsetDrawable) myButton.getBackground();
GradientDrawable shape = (GradientDrawable) drawable.getDrawable();
shape.setColor(Color.BLUE);

我创建了一个自定义的多层drawable,用作按钮的背景。

这里假设myButton是你上面所提到的按钮,并已经被定义了。

android:background="@drawable/custom_button"

编辑

如果要使用API级别为1的方法,请按以下步骤操作:

创建一个名为custom_shape.xml 的可绘制文件:

<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>

编写一个方法来更改此可绘制对象的颜色,并在其周围添加插入物:
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);
}

你能再解释一下吗?这不会使用我定义的custom_button.xml drawable。 - ZakTaccardi
这个库旨在在ICS或更高版本上运行,但4.1也可以。 - ZakTaccardi
请看我上面的编辑。您需要为形状创建一个单独的drawable,然后在程序中将inset包装在它周围。 - Ken Wolf
谢谢Ken。为什么使用android:background="@drawable/custom_button"定义背景很重要?我注意到,如果您通过编程方式设置背景而不是通过XML设置,则涟漪选择器会使用奇怪的颜色。我需要通过编程方式而不是通过XML来完成它。 - ZakTaccardi
让我们在聊天中继续这个讨论 - ZakTaccardi
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接