Android View con View.GONE todavía recibe onTouch y onClick


76

Esto me confunde:

Por lo que he leído, una vista con setVisibility (View.GONE); no debería recibir más eventos de toque o clic. Mi diseño tiene dos partes, que serán visibles o desaparecerán de modo que solo una de ellas sea visible y utilizable a la vez, pero View.GONE no funciona. No puedo ver la vista GONE, como se esperaba, pero aún así reacciona a onClick (y consume el evento que debería obtener la otra vista).

¿Me puedes ayudar?

Quizás sea de interés: cuando comienzo mi proyecto, una vista se ha APAGADO, la otra es visible. Esta vez funcionará como se esperaba (la vista GONE básicamente se ignora), pero después de configurar View.GONE a través del código, dejará de funcionar.


1
¿Está sucediendo esto inmediatamente después de llamar a View.GONE? ¿Solo por un tiempo limitado? Puede que tenga que ver con el hecho de que los cambios en la interfaz de usuario no surten efecto de inmediato.
Cheryl Simon

1
Necesitamos más información. Intente usar la hierarchyviewerherramienta para inspeccionar el estado de su jerarquía de vistas en tiempo de ejecución. Esto le permitirá ver el estado de visibilidad y mucho más al depurar problemas de vista.
adamp

Gracias. Esto sucede inmediatamente después de llamar a View.GONE. La herramienta de visualización de jerarquía dice que la vista se ha ido, pero todavía está recibiendo onClick. Mi plataforma es cyanogenmod 2.2 (pero espero que esto siga siendo un problema en mi código: D)
ShadowMare

Tengo el mismo problema sin animaciones. Incluso cuando establezco todos los elementos de un ViewGroup en GONE, aún puedo seleccionar el contenido de un GONE EditText y obtener el teclado.
philipp

Después de View.GONE, el elemento del diseño recibe el evento onClick (). Esto tiene vista de animación y se ha ido. ¿Cómo bloquear esto?
iBrain

Respuestas:


112

¿Quizás usa animaciones para mostrar / ocultar las vistas? Obtengo este comportamiento cuando uso animaciones que tienen android: fillEnabled = "true" android: fillAfter = "true" No lo entiendo, y parece un error - si uso animaciones sin fillEnabled / fillAfter, todo funciona como se esperaba. ..


2
¿Hay alguna solución alternativa disponible? Estoy usando nineoldandroids y veo este comportamiento en API10; creo que usa fillEnabled para simular el comportamiento de la API 3.0 de modificar las propiedades de la vista después de la animación.
Rafael Nobre

1
También tengo este problema con las API de Android Google 4.4.2.
GuilhE

Gracias, es cierto, esto me ayudó :)
Android Noob

Gracias por la pista, eliminando android: fillAfter = "true", adjunte el oyente de animación con lo que code @Override public void onAnimationEnd(Animation animation) { /* Android will make an exception when you change the view hierarchy * in animationEnd. http://stackoverflow.com/a/7445557/587186 */ new Handler().post(new Runnable() { public void run() { if (interventionPreview != null) { interventionPreview.setVisibility(View.GONE); } } }); } hizo, espero que ayude.
zorro

Gracias por salvarme de un dolor de cabeza menor
Koen Van Looveren

108

Si establece setVisibility(View.GONE)después de alguna animación (desvanecimiento, por ejemplo), intente borrar la animación con clearAnimation(). Eso es lo que me ayudó.


3
Esta es una mejor respuesta. Hay escenarios en los que desea utilizar android:fillAftery android:fillEnableden sus animaciones y desea que la vista deje de responder.
Mick Byrne

1
Este funcionó para mí, pero dado que mi animación durará uno o dos segundos, entonces clearAnimation()detiene la animación y no puedo ver la animación de desvanecimiento. En lugar de ese, lo usé alpha.setFillAfter(false);dentro de mi animación alfa y funcionó exactamente como esperaba.
osayilgan

9
Esta es la mejor respuesta, ¡gracias! @osayilgan, en este caso solo necesita establecer un oyente onEndAnimation y clearAnimation () allí, después de que finalice la animación.
Rafael Nobre

Creo que esta respuesta es mejor que la aceptada, ya que es posible que se desee el comportamiento fillAfter. Gracias, me salvaste un mundo de dolor.
ssawchenko

2
@osayilgan debes poner la clearAnimation()llamada en el onAnimationEnd()método. Entonces funciona como se esperaba.
Saran

8

Intente establecer la propiedad en la que se puede hacer clic en falso usando setClickable (falso) después de setVisibility (View.GONE)


5

Sí, mview.clearAnimation()tienen algunas issuses pero amination.setFillAfter(false);y mview.setClickable(false);funciona perfecto.


2

Lo que espero que suceda es que haga que una vista sea invisible, pero las vistas que los niños aún responden a los clics (es decir, su vista es un grupo de vistas). Podrías hacer algo como:

private void hideTheChildren(View v){
    if(v instanceof ViewGroup) {
        int count = ((ViewGroup)v).getChildCount();
        for(int k = 0 ; k < count ; k++) {
            hideTheChildren(((ViewGroup)v).getChildAt(k));
        }
        v.setVisibility(View.GONE);
    }
    else {
        v.setClickable(false);
        v.setVisibility(View.GONE);
    }
}

por supuesto, entonces también tienes que hacer lo contrario

private void showTheChildren(View v){
    if(v instanceof ViewGroup) {
        int count = ((ViewGroup)v).getChildCount();
        for(int k = 0 ; k < count ; k++) {
            showTheChildren(((ViewGroup)v).getChildAt(k));
        }
        v.setVisibility(View.VISIBLE);
    }
    else {
        v.setClickable(true);
        v.setVisibility(View.VISIBLE);
    }
}

Esto me ha funcionado en el pasado. Actualmente no conozco una mejor manera de hacer esto.


1
Después de 8 años, esto sigue siendo un problema. Esto funcionará siempre que no tenga otra vista detrás.
Tamoxin

1

Hubiera publicado esto como comentario, pero desafortunadamente no pude publicar un comentario. Como podría ser una posible solución para usted, lo publico de esa manera:

Mientras escribe "onClick", supongo que está utilizando el onClickatributo en su diseño XML. Intente establecer un OnClickListenercon en setOnClickListenerlugar del onClickatributo. Quizás esto ayude ...


Gracias por su respuesta. Ya estoy usando setOnClickListener en lugar de la etiqueta xml.
ShadowMare

1

Para aquellos que respondieron anteriormente y aún no resolvieron sus problemas, recomiendo eliminar la vista de la vista principal. Si necesita mostrar la vista nuevamente, simplemente haga una copia y agréguela a la vista principal.

Esto puede parecer excesivo, pero estaba ocultando / mostrando grupos de vista completos en su caso, podría ser un botón, una vista de texto o una imagen, esta solución seguirá funcionando.


2
En realidad, esto es lo único que funcionó para mí. NOTA: Estaba usando una vista para cubrir otra vista BottomSheetBehaviormientras cargaba datos. Con todas las demás respuestas, la vista siguió interceptando los toques / gestos. Y esto rompió mi BottomSheetBehaviour| Android 8.0 con design-support-lib 27.0.2
Entreco

0

intente agregar .clearAnimation () en la anulación onAnimationEnd.


0

si tiene una animación en la vista, debe llamar a view.clearAnimation.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.