studio gestos eventos evento deslizar dedo android android-5.0-lollipop rippledrawable

gestos - ontouchevent android



¿Cómo activar el efecto de rizo en Android Lollipop, en una ubicación específica dentro de la vista, sin activar eventos táctiles? (4)

¡Sí hay! Para desencadenar una ondulación programáticamente, debe establecer el estado de RippleDrawable con setState() . ¡Llamar a setVisible() NO funciona!

La solución

Para mostrar la ondulación, debe establecer el estado en presionado y habilitado al mismo tiempo:

rippleDrawable.setState(new int[] { android.R.attr.state_pressed, android.R.attr.state_enabled });

La ondulación se mostrará siempre que se establezcan esos estados. Cuando quiera ocultar la ondulación nuevamente, establezca el estado en un int[] vacío int[] :

rippleDrawable.setState(new int[] { });

Puede establecer el punto desde el que emana la ondulación llamando a setHotspot() .

Cómo funciona

He depurado mucho y he estudiado el código fuente de RippleDrawable hacia arriba y hacia abajo hasta que me di cuenta de que la ondulación se activa en onStateChange() . Llamar a setVisible() no tiene ningún efecto y nunca hace que aparezca ninguna ondulación.

La parte relevante del código fuente de RippleDrawable es esta:

@Override protected boolean onStateChange(int[] stateSet) { final boolean changed = super.onStateChange(stateSet); boolean enabled = false; boolean pressed = false; boolean focused = false; for (int state : stateSet) { if (state == R.attr.state_enabled) { enabled = true; } if (state == R.attr.state_focused) { focused = true; } if (state == R.attr.state_pressed) { pressed = true; } } setRippleActive(enabled && pressed); setBackgroundActive(focused || (enabled && pressed)); return changed; }

Como puede ver si los atributos habilitado y presionado están configurados, tanto la ondulación como el fondo se activarán y la ondulación se mostrará. Además, siempre que establezca el estado enfocado, el fondo también se activará. Con esto puede activar la ondulación y hacer que el fondo cambie de color de forma independiente.

Si está interesado, puede ver el código fuente completo de RippleDrawable here .

Esta es una pregunta corta:

Supongamos que tengo una View con el RippleDrawable como fondo.

¿Hay una manera fácil de desencadenar la ondulación desde una posición específica sin activar ningún evento táctil o de clic?


Aquí está la combinación de setHotSpot () y https://.com/a/25415471/1474113 de Nikola

private void forceRipple(View view, int x, int y) { Drawable background = view.getBackground(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && background instanceof RippleDrawable) { background.setHotspot(x, y); } view.setPressed(true); // For a quick ripple, you can immediately set false. view.setPressed(false); }


Incorporé / combiné las respuestas de @Xaver Kapeller y @Nikola Despotoski arriba:

protected void forceRippleAnimation(View view) { Drawable background = view.getBackground(); if(Build.VERSION.SDK_INT >= 21 && background instanceof RippleDrawable) { final RippleDrawable rippleDrawable = (RippleDrawable) background; rippleDrawable.setState(new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled}); Handler handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { rippleDrawable.setState(new int[]{}); } }, 200); } }

Para forzar mediante programación un efecto de rizado en el comando, simplemente llame a forceRippleAnimation (), pasando la vista que desea ondular como parámetro.


Primero, necesitas obtener el dibujo desde la Vista.

private void forceRippleAnimation(View v, float x, float y){ Drawable background = v.getBackground(); if(background instanceof RippleDrawable){ RippleDrawable ripple = (RippleDrawable)background; ripple.setHotspot(x, y); ripple.setVisible (true, true); } }

Método setHotspot(x,y); se utiliza para establecer desde donde se iniciará la animación de rizado; de lo contrario, si no se configura, RippleDrawable llevará el Rect donde reside (es decir, el Rect de la Vista donde se establece como fondo) e iniciará el efecto de rizo desde el centro.

setVisible(true, true) hará que el dibujo sea visible y el último argumento forzará la animación independientemente del estado actual del dibujo.