具有不同颜色和相同样式的按钮

时间:2012-06-13 14:15:40

标签: android button colors styles

我正在开发一个应用程序,其中包含通过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种不同的xmls不是正确的方法。

所有android:状态的startColor和endColor值都从网上下载并保存到数据库中,我不知道它们中有多少个。

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

所以我的问题是,我可以在colors.xml中动态更改颜色吗?这样的事情

List<Colors> colors = downloadColorsFromWeb();

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

提前谢谢大家。

nosko。

2 个答案:

答案 0 :(得分:0)

您可以为下载的每种颜色动态生成drawable。检查GradientDrawable类。我认为您可以在初始化期间提供开始/结束颜色,然后设置笔划和角半径属性。但你必须自己找出填充物。我不确定。

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

中使用它

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

edit2:你可以setState到drawable但我不知道如何为按钮的每个状态设置不同的背景drawable。

答案 1 :(得分: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 }));