Je crois que ce que vous voulez faire, c'est que vos boutons affichent différents dégradés lorsqu'ils sont dans l'état normal, l'état enfoncé, l'état focalisé, etc. Cela peut être fait en utilisant XML (Créer un fichier selector.xml dans res/drawable qui fait référence à des fichiers shape.xml dans res/drawable contenant chacun un élément dégradé, puis définit l'arrière-plan de votre bouton dans le fichier selector.xml que vous avez créé.) Toutefois, la route XML vous permet uniquement de définir des dégradés avec deux (ou éventuellement trois) couleurs statiques et sans aucun contrôle sur l'emplacement des points d'arrêt de la couleur. Une solution programmatique vous donnera beaucoup plus de flexibilité et vous permettra de changer dynamiquement les couleurs. Voici un exemple pour un projet Android appelé GradientLab.
main.xml dans res/mises en page:
<?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 dans res/valeurs:
<?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 en android.examples que des démonstrations en utilisant des gradients de boutons:
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 dans android.examples qui sélectionne les dégradés basés sur l'état du bouton:
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 dans android.examples qui peint la 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 en android.examples qui gère les transitions réelles:
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;
}
}