2010-03-08 52 views
2

我必須創建一個帶漸變填充的彩色按鈕(從Y軸按鈕的中間開始)。如果我設置的按鈕,我想要的顏色的背景屬性,我失去了圓潤按鈕外觀和感覺也漸變填充(它看起來像一個背景TextView)。如何漸變填充按鈕的背景?

另外,我還要當用戶按下按鈕這種顏色改變。我可以通過選擇器XML(Color State Lists)指定它嗎?

,可以幫助我在這裏的任何教程或鏈接表示讚賞。

謝謝。

回答

5

How to set background color of a View

您需要定義一個自定義StateListDrawable資源,從一個Android使用由默認的按鈕,在這裏你改變了九補丁圖像是梯度也許克隆。你可能能夠用XML定義這些漸變,這意味着它們可以很好地伸展。

8

我相信你想要做的是讓你的按鈕顯示不同的梯度時,在正常狀態下,按下狀態,集中狀態,等等。這可以通過使用XML完成(創建一個資源文件selector.xml/drawable引用res/drawable中的shape.xml文件,每個文件都包含一個漸變元素,然後將按鈕的背景設置爲您創建的selector.xml文件。)但是,XML路徑只允許您使用兩個漸變定義(或可選地三個)靜態顏色並且不控制彩色停止點的位置。程序化解決方案將爲您提供更大的靈活性,並允許您動態更改顏色。以下是一個名爲GradientLab的Android項目的示例。

main.xml中在res /佈局:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" 
    style="@style/LayoutArea" 
> 
<TextView 
    style="@style/LayoutRow" 
    android:text="@string/hello" /> 
<Button 
    style="@style/RowButton" 
    android:id="@+id/btn1" 
    android:text="1" /> 
<Button 
    style="@style/RowButton" 
    android:id="@+id/btn2" 
    android:text="2" /> 
<Button 
    style="@style/RowButton" 
    android:id="@+id/btn3" 
    android:text="3" /> 
</LinearLayout> 

styles.xml在res /值:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
<style name="LayoutArea"> 
    <item name="android:layout_width">fill_parent</item> 
    <item name="android:layout_height">fill_parent</item> 
</style> 
<style name="LayoutRow"> 
    <item name="android:layout_width">fill_parent</item> 
    <item name="android:layout_height">wrap_content</item> 
</style> 
<style name="LayoutColumn"> 
    <item name="android:layout_width">wrap_content</item> 
    <item name="android:layout_height">fill_parent</item> 
</style> 
<style name="LayoutItem"> 
    <item name="android:layout_width">wrap_content</item> 
    <item name="android:layout_height">wrap_content</item> 
</style> 
<style name="RowButton" parent="LayoutRow"> 
    <item name="android:layout_weight">1</item> 
    <item name="android:layout_margin">8dp</item> 
    <item name="android:gravity">center_horizontal</item> 
</style> 
</resources> 

GradientLab.java中,使用梯度的按鈕演示android.examples:

package android.example; 

import android.app.Activity; 
import android.graphics.Color; 
import android.os.Bundle; 
import android.widget.Button; 
import android.widget.LinearLayout; 

public class GradientLab extends Activity { 
    // Layout fields 
    protected LinearLayout mainLayout; 
    public static Button btn1 = null; 
    public static Button btn2 = null; 
    public static Button btn3 = null; 

    // Members 
    private int[] normalColors = new int[4]; 
    private int[] focusedColors = new int[2]; 
    private int[] disabledColors = new int[1]; 
    private int defaultSkinR = 94; 
    private int defaultSkinG = 128; 
    private int defaultSkinB = 219; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     /* 
     * This creates View objects from the xml file. The xml file should 
     * define all views and all static attributes. 
     */ 
     mainLayout = (LinearLayout) getLayoutInflater().inflate(R.layout.main, 
       null); 

     normalColors[0] = Color.argb(255, defaultSkinR, defaultSkinG, 
       defaultSkinB); 
     normalColors[1] = Color.argb(255, 217, 217, 217); 
     normalColors[2] = Color.argb(191, defaultSkinR, defaultSkinG, 
       defaultSkinB); 
     normalColors[3] = Color.argb(140, defaultSkinR, defaultSkinG, 
       defaultSkinB); 

     focusedColors[0] = Color.argb(229, 242, 242, 242); 
     focusedColors[1] = Color.BLUE; 

     UIGradientSelector gradientSelector1 = new UIGradientSelector(
       normalColors, focusedColors, null); 
     UIGradientSelector gradientSelector2 = new UIGradientSelector(
       normalColors, focusedColors, null); 

     disabledColors[0] = Color.argb(153, 216, 216, 216); 
     UIGradientDrawable disabledGradient = new UIGradientDrawable(
       disabledColors); 

     btn1 = (Button) mainLayout.findViewById(R.id.btn1); 
     btn1.setBackgroundDrawable(gradientSelector1); 

     btn2 = (Button) mainLayout.findViewById(R.id.btn2); 
     btn2.setBackgroundDrawable(gradientSelector2); 

     btn3 = (Button) mainLayout.findViewById(R.id.btn3); 
     btn3.setBackgroundDrawable(disabledGradient); 

     setContentView(mainLayout); 
    } 
} 

android.examples中基於按鈕狀態選擇漸變的UIGradientSelector.java:

package android.example; 

import android.graphics.drawable.StateListDrawable; 

/** 
* {@link StateListDrawable} that controls selection of 
* {@link UIGradientDrawable} based on the three basic button states. 
*/ 
public class UIGradientSelector extends StateListDrawable { 

    /** 
    * {@link UIGradientSelector} that selects the {@link UIGradientDrawable} 
    * defined by the colors for the three basic button states. 
    * 
    * @param normalColors 
    *   Array of primitive ints that define the gradient colors for a 
    *   button in its normal state. 
    * @param focusedColors 
    *   Array of primitive ints that define the gradient colors for a 
    *   button in its focused state. 
    * @param pressedColors 
    *   Array of primitive ints that define the gradient colors for a 
    *   button in its pressed state. If the array is null, then 
    *   focusedColors will be used for the pressed state. 
    */ 
    public UIGradientSelector(int[] normalColors, int[] focusedColors, 
      int[] pressedColors) { 
     int stateFocused = android.R.attr.state_focused; 
     int statePressed = android.R.attr.state_pressed; 
     UIGradientDrawable normalGradient = new UIGradientDrawable(normalColors); 
     UIGradientDrawable focusedGradient = new UIGradientDrawable(
       focusedColors); 
     UIGradientDrawable pressedGradient; 

     if (pressedColors == null) { 
      pressedGradient = focusedGradient; 
     } else { 
      pressedGradient = new UIGradientDrawable(pressedColors); 
     } 

     addState(new int[] { stateFocused }, focusedGradient); 
     addState(new int[] { statePressed }, pressedGradient); 
     addState(new int[] { -statePressed, -stateFocused }, normalGradient); 
    } 
} 

UIGradientDrawable.java在android.examples該油漆的表面:

package android.example; 

import android.graphics.drawable.PaintDrawable; 
import android.graphics.drawable.shapes.RectShape; 

/** 
* {@link PaintDrawable} that paints the surface via a {@link UIGradientShader}. 
*/ 
public class UIGradientDrawable extends PaintDrawable { 

    /** 
    * {@link UIGradientDrawable} with an initial shape of a rounded rectangle 
    * that transitions evenly between the specified colors. 
    * 
    * @param colors 
    *   Array of primitive ints that contain the argb values of the 
    *   color to use for transitioning. 
    */ 
    public UIGradientDrawable(int[] colors) { 
     UIGradientShader gradientShader = new UIGradientShader(colors); 
     setShape(new RectShape()); 
     setCornerRadius(8); 
     setShaderFactory(gradientShader); 
     setDither(true); 
    } 

} 

UIGradientShader.java在android.examples處理該實際轉換:

package android.example; 

import android.graphics.Color; 
import android.graphics.LinearGradient; 
import android.graphics.Shader; 
import android.graphics.drawable.ShapeDrawable.ShaderFactory; 

/** 
* {@link ShaderFactory} that uses a {@link LinearGradient} to transition 
* between specified colors. Any number of colors may be specified. 
*/ 
public class UIGradientShader extends ShaderFactory { 
    private int[] colors; 
    private float[] positions; 

    /** 
    * {@link UIGradientShader} that spaces color transitions evenly across the 
    * painting surface. 
    * 
    * @param colors 
    *   Array of primitive ints that contain the argb values of the 
    *   color to use for transitioning. If the array contains only one 
    *   color, then an argb of (0, 0, 0, 0) will be used for the end 
    *   color of the transition. If the array is set to null or 
    *   contains zero colors, then the transition will be from an argb 
    *   of (255, 255, 255, 255) to and argb of (0, 0, 0, 0). 
    * 
    * @see Color 
    */ 
    public UIGradientShader(int[] colors) { 
     init(colors, null); 
    } 

    /** 
    * {@link UIGradientShader} that spaces color transitions across the 
    * painting surface as specified. 
    * 
    * @param colors 
    *   Array of primitive ints that contain the argb values of the 
    *   color to use for transitioning. If the array contains only one 
    *   color, then an argb of (0, 0, 0, 0) will be used for the end 
    *   color of the transition. If the array is set to null or 
    *   contains zero colors, then the transition will be from an argb 
    *   of (255, 255, 255, 255) to and argb of (0, 0, 0, 0). 
    * @param positions 
    *   Array of primitive floats that contain the position of the 
    *   transition points. If the array is null, then the color 
    *   transitions will be spaced evenly. 
    */ 
    public UIGradientShader(int[] colors, float[] positions) { 
     init(colors, positions); 
    } 

    private void init(int[] colors, float[] positions) { 
     if (colors == null || colors.length == 0) { 
      this.colors = new int[2]; 
      this.colors[0] = Color.argb(255, 255, 255, 255); 
      this.colors[1] = Color.argb(0, 0, 0, 0); 
     } else if (colors.length == 1) { 
      this.colors = new int[2]; 
      this.colors[0] = colors[0]; 
      this.colors[1] = Color.argb(0, 0, 0, 0); 
     } else { 
      this.colors = colors; 
     } 

     this.positions = positions; 
    } 

    public Shader resize(int width, int height) { 
     LinearGradient lg = new LinearGradient(0, 0, 0, height, colors, 
       positions, Shader.TileMode.REPEAT); 
     return lg; 
    } 

}