2012-06-13 2 views
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> 

@ вытяжка/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> 

All свойства, такие как прокладка, ход, радиус одинаковы, кроме цветов градиента в разных состояниях. Моя проблема в том, что мое приложение должно иметь больше стилей. Вы можете представить это, поскольку у вас есть список цветов, и когда вы выбираете одно приложение, все цвета меняются на выбранный. Так что, если у вас 20 цветов, 20 разных xmls - неправильный путь.

Оба значения startColor и endColor для всех android: состояния загружаются из сети и сохраняются в DB, ​​и я не знаю, сколько из них есть.

Есть ли способ достичь такого поведения? Я искал все форумы, и большинство ответов было то, что это невозможно. Я нашел одно «решение», переписывающее colors.xml, но это не кажется лучшим решением для меня.

Так что мой вопрос: могу ли я динамически изменять цвет в цветах.xml? Что-то вроде этого

List<Colors> colors = downloadColorsFromWeb(); 

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

Спасибо всем заранее.

nosko.

ответ

0

Возможно, вы можете динамически генерировать извлекаемый для каждого загружаемого вами цвета. Проверьте класс GradientDrawable. Я думаю, что вы можете предоставить цвета начала/конца во время инициализации и после этого установить свойства радиуса и угла. Но вам нужно будет узнать о прокладке самостоятельно. Я не уверен.

После создания вытяжки, вы можете использовать его в данных кнопках setBackgroundDrawable

редактировании: возможно установка отступов баттона будет делать трюк

edit2: вы можете setState к вытяжке, но я не уверен, как установить различные фоновые рисунки для каждого состояния кнопки.

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 })); 
Смежные вопросы