How do gradient fill buttons background?

I need to create a colored button with a gradient fill (starting from the middle of the button along the Y axis). If I set the button's background property to the color that I want, I lose the rounded appearance of the button, as well as the gradient fill (this looks like a TextView with a background).

In addition, I want this color to change when the user clicks a button. Can I specify this using selector XML ( Color State Lists )?

Any tutorials or links that may help me here are welcome.

Thanks.

+2
android android-ui
source share
2 answers

How to set the background color in a view

You will need to define your own StateListDrawable resource, cloned, possibly from one Android, used for the default buttons, where you change the images with nine patches to be gradients. You could define these gradients in XML, which would mean they would stretch nicely.

+5
source share

I believe that you want your buttons to display different gradients when they are in normal state, pressed state, focused state, etc. This can be done using XML (create a selector.xml file in res / which refers to shape.xml files in res / drawable, each of which contains a gradient element, and then sets the background of your button to the selector.xml file that you created. ) However, the XML route will allow you to define gradients with two (or possibly three) static colors and without control over the location of the color breakpoints. The software solution will give you much greater flexibility and allow you to dynamically change colors. Here is an example Android project called GradientLab.

main.xml in res / layouts:

 <?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 in res / values:

 <?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 in android.examples that demonstrates using gradients with buttons:

 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); } } 

UIGradientSelector.java in android.examples, which selects the gradient base in the button state:

 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 in android.examples that paints the surface:

 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 in android.examples files that handle the actual transitions:

 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; } } 
+8
source share

All Articles