móviles - manual de programacion android pdf
¿Cómo usar RippleDrawable mediante programación en código(no xml) con Android 5.0 Lollipop? (3)
Tengo el siguiente código para mi ondulación:
<?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>
Ahora quiero dar al usuario la posibilidad de elegir colores propios, por lo que necesito crear la ondulación programáticamente.
Encontré this y creo que esta es la forma correcta de hacerlo, pero no sé cómo manejar esto.
La ondulación será utilizada aquí:
<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" />
Necesito establecer el fondo en un RippleDrawable
como este:
addButton.setBackground(ripple);
Así fue como pude lograr esto.
Tenga en cuenta que esto es solo Api 21+, por lo que tendrá que recurrir a un Drawable normal si admite versiones inferiores.
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: Hice algunos retoques más y descubrí que ColorStateList no necesita ser tan complejo como la solución anterior. Lo he simplificado al siguiente fragmento. (Todo lo demás en el bloque de código anterior es el mismo. Solo cambié la creación de ColorStateList). Dejaré el bloque anterior como el original, en caso de que este método no funcione para alguien.
new ColorStateList(
new int[][]
{
new int[]{}
},
new int[]
{
pressedColor
}
);
Básicamente, necesitas crear un nuevo objeto RippleDrawable. Para dispositivos pre-Lollipop, desea un StateListDrawable (como otros ya han sugerido). He escrito un GIST algo ingenioso con un montón de métodos útiles relacionados con Dibujos y colores: https://gist.github.com/milosmns/6566ca9e3b756d922aa5
Lo más probable es que desee usar #getBackgroundDrawable()
de ese singleton.
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;
}
Puede obtener el drawable y aplicar a cualquier vista usando view.setDrawable
.
Para los dispositivos Lollipop + obtendrá una ondulación, de lo contrario cambiará el color de la vista.