Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


¿Cómo activar el efecto de rizo en Android Lollipop, en una ubicación específica dentro de la vista, sin desencadenar eventos de touch?

Esta es una pregunta corta:

Supongamos que tengo una View con RippleDrawable como fondo.

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

  • Lollipop RippleDrawable vs Selector para Pre-Lollipop
  • Touch feedback con RecyclerView y CardView
  • Cómo crear efecto de rizo para pre-lollipop
  • Crear una ondulación dibujable sin transparencia
  • ¿Cómo hacer una ondulación circular en un botón cuando se está haciendo clic?
  • RippleDrawable máscara de color, ¿para qué sirve?
  • ¿Cómo manejar el efecto Ripple en 9-patch y CardView, y tener control sobre los estados del selector?
  • Cómo utilizar RippleDrawable programaticamente en código (no xml) con Android 5.0 Lollipop?
  • 4 Solutions collect form web for “¿Cómo activar el efecto de rizo en Android Lollipop, en una ubicación específica dentro de la vista, sin desencadenar eventos de touch?”

    ¡Sí hay! Para desencadenar una ondulación programatically usted tiene que fijar el estado del RippleDrawable con setState() . Llamar setVisible() NO funciona!


    La solución

    Para mostrar la ondulación tiene que configurar el estado para que se presione y se active 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 dichos estados. Cuando desee ocultar la ondulación nuevamente establezca el estado en un int[] vacío int[] :

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

    Puede establecer el punto desde el cual setHotspot() el ripple llamando a setHotspot() .


    Cómo funciona

    He depurado mucho y estudiado el código fuente de RippleDrawable arriba y abajo hasta que me di cuenta de que la ondulación es en realidad desencadenada en onStateChange() . Llamar setVisible() no tiene efecto y nunca hace que aparezca ninguna ondulación.

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

     @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 se puede ver si el atributo activado y presionado se establecen, tanto la ondulación como el fondo se activarán y se mostrará la ondulación. Además, siempre y cuando se establece el estado de enfoque el fondo se activará también. Con esto usted puede accionar la ondulación y tener el color del fondo cambia independientemente.

    Si está interesado, puede ver todo el código fuente de RippleDrawable aquí .

    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 programaticamente un efecto de ondulación en el comando, simplemente llame a forceRippleAnimation (), pasando la vista que desea ondular como parámetro.

    En primer lugar, usted necesita para obtener el dibujable de 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 ondulación, de lo contrario si no se establece, el RippleDrawable tomará el Rect donde reside (es decir, el Rect de la vista donde se establece como fondo) y comenzará el efecto de rizo desde el centro.

    setVisible(true, true) hará que el argumento visible visible y el último argumento setVisible(true, true) animación sin importar el estado de dibujo actual.

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

     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); } 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.