0

我正在开发一个应用程序,其中包含一些通过 layout.xml 定义的按钮,如下所示

<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/largebutton" >
</Button>

@drawable/largebutton 看起来像这样

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

    <item android:state_pressed="true" >
        <shape>
            <gradient android:startColor="@color/menu_button_active_start" android:endColor="@color/menu_button_active_end" android:angle="270" />
            <stroke android:width="@dimen/largebutton_stroke" android:color="@color/menu_button_stroke" />
            <corners android:radius="@dimen/largebutton_radius" />
            <padding android:left="@dimen/largebutton_padding_leftright" android:top="@dimen/largebutton_padding_topbottom" android:right="@dimen/largebutton_padding_leftright" android:bottom="@dimen/largebutton_padding_topbottom" />
        </shape>
    </item>

    <item android:state_focused="true" >
        <shape>
            <gradient android:startColor="@color/menu_button_focused_start" android:endColor="@color/menu_button_focused_end" android:angle="270" />
            <stroke android:width="@dimen/largebutton_stroke" android:color="@color/menu_button_focused_stroke" />
            <corners android:radius="@dimen/largebutton_radius" />
            <padding android:left="@dimen/largebutton_padding_leftright" android:top="@dimen/largebutton_padding_topbottom" android:right="@dimen/largebutton_padding_leftright" android:bottom="@dimen/largebutton_padding_topbottom" />
        </shape>
    </item>
 .....
</selector>

除了不同状态下的渐变颜色外,所有属性,如填充、描边、半径都是相同的。我的问题是我的应用程序必须有更多样式。您可以将其想象为拥有颜色列表,并且当您选择一个应用程序时,会将所有颜色更改为选定的一种。因此,如果您有 20 种颜色,则 20 种不同的 xml 不是正确的方法。

所有 android:states 的 startColor 和 endColor 值都是从 Web 下载并保存到 DB 中的,我不知道其中有多少。

有没有办法实现这种行为?我搜索了所有论坛,大多数答案是不可能的。我找到了一个覆盖 colors.xml 的“解决方案”,但它似乎不是我的最佳解决方案。

所以我的问题是,我可以在colors.xml 中动态改变颜色吗?像这样的东西

List<Colors> colors = downloadColorsFromWeb();

Button b = new Button;
b.setDrawable(drawable.with(colors));

谢谢大家。

诺斯科。

4

2 回答 2

0

您可能可以为下载的每种颜色动态生成一个可绘制对象。检查 GradientDrawable 类。我认为您可以在初始化期间提供开始/结束颜色,然后设置笔触和角半径属性。但是你必须自己找出填充物。我不知道。

创建drawable后,您可以在按钮的setBackgroundDrawable

编辑:可能设置按钮的填充可以解决问题

edit2:您可以setState绘制可绘制对象,但我不确定如何为按钮的每个状态设置不同的可绘制背景。

于 2012-06-13T15:06:34.310 回答
0

谢谢@stan0 的回复,它帮助很大,尤其是GradientDrawable 类。

我编写了简单的类来创建按钮并可以根据其状态设置样式。也许它对某人有帮助:)

import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.GradientDrawable.Orientation;
import android.util.AttributeSet;
import android.widget.Button;

/**
 * @author nosko
 *
 */
public class TabButton extends Button {

    private Context c;
    private GradientDrawable selected, focused, pressed, normal;

    public void setNormalState(GradientDrawable gd) {
        this.normal = gd;
    }

    public void setSelectedState(GradientDrawable gd) {
        this.selected = gd;
    }

    public void setFocusedState(GradientDrawable gd) {
        this.focused = gd;
    }

    public void setPressedState(GradientDrawable gd) {
        this.pressed = gd;
    }

    public TabButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub

        selected = pressed = focused = normal = new GradientDrawable(Orientation.TOP_BOTTOM, new int[] { Color.WHITE, Color.DKGRAY });

        this.c          = context;
        this.setPadding(8, 8, 8, 8);        
    }


    /**
     * Change colors when button's state changes
     */
    protected void drawableStateChanged() {

        normal.setCornerRadius(8);
        normal.setStroke(2, Color.parseColor(c.getResources().getString(R.color.tab_button_border)));
        normal.setShape(GradientDrawable.RECTANGLE);
        this.setBackgroundDrawable(normal);

        if (isSelected()) {

            selected.setCornerRadius(8);
            selected.setStroke(2, Color.parseColor(c.getResources().getString(R.color.tab_button_border)));
            selected.setShape(GradientDrawable.RECTANGLE);
            this.setBackgroundDrawable(selected);
        }

        if (isFocused()) {
            focused.setCornerRadius(8);
            focused.setStroke(2, Color.parseColor(c.getResources().getString(R.color.tab_button_border)));
            focused.setShape(GradientDrawable.RECTANGLE);
            this.setBackgroundDrawable(focused);
        }

        if (isPressed()) {
            pressed.setCornerRadius(8);
            pressed.setStroke(2, Color.parseColor(c.getResources().getString(R.color.tab_button_border)));
            pressed.setShape(GradientDrawable.RECTANGLE);
            this.setBackgroundDrawable(pressed);
        }
    }

}

并像这样使用它

TabButton b = new TabButton(context, null);

b.setNormalState(new GradientDrawable(Orientation.TOP_BOTTOM, new int[] { Color.RED, Color.CYAN }));
b.setSelectedState(new GradientDrawable(Orientation.TOP_BOTTOM, new int[] { Color.YELLOW, Color.BLUE }));
b.setFocusedState(new GradientDrawable(Orientation.TOP_BOTTOM, new int[] { Color.YELLOW, Color.GREEN }));
b.setPressedState(new GradientDrawable(Orientation.TOP_BOTTOM, new int[] { Color.YELLOW, Color.BLACK }));
于 2012-06-14T12:47:03.077 回答