J'ai le code suivant pour mon ondulation:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:color="?android:colorControlHighlight">
<item Android:id="@+id/rip">
<shape Android:shape="oval">
<solid Android:color="?android:colorAccent"/>
</shape>
</item>
</ripple>
Maintenant, je veux donner à l'utilisateur la possibilité de choisir ses propres couleurs, je dois donc créer l'ondulation par programme.
J'ai trouvé ceci et je pense que c'est la bonne façon de le faire, mais je ne sais pas comment gérer cela.
L'ondulation sera utilisée ici:
<ImageButton
Android:id="@+id/add_button"
Android:layout_width="@dimen/diameter"
Android:layout_height="@dimen/diameter"
Android:layout_gravity="end|bottom"
Android:layout_marginBottom="@dimen/add_button_margin"
Android:layout_marginEnd="@dimen/add_button_margin"
Android:layout_alignParentBottom="true"
Android:layout_alignParentEnd="true"
Android:src="@drawable/ic_action_add_person"
Android:tint="@Android:color/white"
Android:background="@drawable/oval_ripple"
Android:elevation="@dimen/elevation_low"
Android:stateListAnimator="@anim/button_elevation"
Android:contentDescription="Neuer Spieler" />
Je dois définir l'arrière-plan sur un RippleDrawable
comme ceci:
addButton.setBackground(ripple);
C'est ainsi que j'ai pu y parvenir.
Notez qu'il s'agit d'Api 21+ uniquement, vous devrez donc revenir à un Drawable normal si vous prenez en charge les versions inférieures.
public static RippleDrawable getPressedColorRippleDrawable(int normalColor, int pressedColor)
{
return new RippleDrawable(getPressedColorSelector(normalColor, pressedColor), getColorDrawableFromColor(normalColor), null);
}
public static ColorStateList getPressedColorSelector(int normalColor, int pressedColor)
{
return new ColorStateList(
new int[][]
{
new int[]{Android.R.attr.state_pressed},
new int[]{Android.R.attr.state_focused},
new int[]{Android.R.attr.state_activated},
new int[]{}
},
new int[]
{
pressedColor,
pressedColor,
pressedColor,
normalColor
}
);
}
public static ColorDrawable getColorDrawableFromColor(int color)
{
return new ColorDrawable(color);
}
Edit: J'ai bricolé avec cela un peu plus et découvert que ColorStateList n'a pas besoin d'être presque aussi complexe que la solution ci-dessus. Je l'ai simplifié pour l'extrait ci-dessous. (Tout le reste dans le bloc de code ci-dessus est le même. Je n'ai changé que la création de ColorStateList.) Je laisserai le bloc ci-dessus comme original, au cas où cette méthode ne fonctionnerait pas pour quelqu'un.
new ColorStateList(
new int[][]
{
new int[]{}
},
new int[]
{
pressedColor
}
);
public static Drawable getAdaptiveRippleDrawable(
int normalColor, int pressedColor) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
return new RippleDrawable(ColorStateList.valueOf(pressedColor),
null, getRippleMask(normalColor));
} else {
return getStateListDrawable(normalColor, pressedColor);
}
}
private static Drawable getRippleMask(int color) {
float[] outerRadii = new float[8];
// 3 is radius of final ripple,
// instead of 3 you can give required final radius
Arrays.fill(outerRadii, 3);
RoundRectShape r = new RoundRectShape(outerRadii, null, null);
ShapeDrawable shapeDrawable = new ShapeDrawable(r);
shapeDrawable.getPaint().setColor(color);
return shapeDrawable;
}
public static StateListDrawable getStateListDrawable(
int normalColor, int pressedColor) {
StateListDrawable states = new StateListDrawable();
states.addState(new int[]{Android.R.attr.state_pressed},
new ColorDrawable(pressedColor));
states.addState(new int[]{Android.R.attr.state_focused},
new ColorDrawable(pressedColor));
states.addState(new int[]{Android.R.attr.state_activated},
new ColorDrawable(pressedColor));
states.addState(new int[]{},
new ColorDrawable(normalColor));
return states;
}
Vous pouvez obtenir le dessin et appliquer à n'importe quelle vue en utilisant view.setDrawable
.
Pour les appareils Lollipop +, vous obtiendrez une ondulation sinon cela changera la couleur de la vue.
Fondamentalement, vous devez créer un nouvel objet RippleDrawable. Pour les appareils pré-Lollipop, vous voulez un StateListDrawable (comme d'autres l'ont déjà suggéré). J'ai écrit un Gist quelque peu ingénieux avec un tas de méthodes utiles liées aux Drawables et à la coloration: https://Gist.github.com/milosmns/6566ca9e3b756d922aa5
Vous voudrez probablement utiliser #getBackgroundDrawable()
à partir de ce singleton.