¿Cómo pasar el evento onClick de una vista a su padre en Android?


100

Tengo un TextView en un diseño cuyo fondo es un Selector. Y el texto de TextView se establece en Spanned from HTML. Luego configuro TextView con LinkMovementMethod.

Ahora, cuando toco TextView, el evento de clic no se envía a su diseño principal para activar el selector.

¿Cómo debería solucionarse esto?

Respuestas:


45

Creo que necesita usar uno de esos métodos para poder interceptar el evento antes de que se envíe a los componentes apropiados:

Activity.dispatchTouchEvent(MotionEvent) - Esto permite que su Actividad intercepte todos los eventos táctiles antes de que se envíen a la ventana.

ViewGroup.onInterceptTouchEvent(MotionEvent) - Esto permite que un ViewGroup observe los eventos a medida que se envían a las Vistas secundarias.

ViewParent.requestDisallowInterceptTouchEvent(boolean) - Invoque esto en una Vista principal para indicar que no debe interceptar eventos táctiles con onInterceptTouchEvent (MotionEvent).

Más información aquí .

Espero que ayude.


1
¿Existe una manera más fácil de pasar los eventos para activar onClick y onLongClick en la vista principal, o tengo que implementarlos yo mismo?
shiami

Mira esto: stackoverflow.com/questions/2136696/pass-event-to-parent-view Posiblemente quieras intentar pasar el mismo oyente de clics a las otras instancias como se sugiere, aunque no sé si funcionará , pero valdría la pena intentarlo.
Luis Miguel Serrano

La respuesta a continuación es mucho más limpia
JPM

¿Debo crear una instancia de MotionEvent? Por favor, explique, @LuisMiguelSerrano
olegario

@olegario, normalmente redefine el método, por ejemplo, para dispatchTouchEvent, con @Override, para definir un nuevo comportamiento para él, por lo que solo recibe un evento de movimiento que el sistema ha proporcionado a su actividad (u otro componente de su aplicación), y usted trátelo y / o reenvíe a cualquier número de componentes secundarios de acuerdo con sus propias reglas. Algo como: @Override public boolean dispatchTouchEvent(MotionEvent ev) { ... }
Luis Miguel Serrano

212

Declarar su TextViewno se puede hacer clic / enfocable mediante el uso android:clickable="false"y android:focusable="false"o v.setClickable(false)y v.setFocusable(false). Los eventos de clic deben enviarse al TextViewpadre de 'ahora.

Nota:

Para lograr esto , debe agregar clic a su directo parent. o establecer android:clickable="false"y android:focusable="false"a su padre directo para pasar el oyente a otro padre .


1
Oh hombre, si pudiera dar esto +100 lo haría. ¡He intentado descubrir cómo hacer que un clic solo funcione en un ViewPager y no en el diseño de los adaptadores con TouchImageView implementando onTouch! Esta solución funcionó a las mil maravillas.
JPM

1
pero ¿qué pasa si quiero manejar el evento de cambio de enfoque de EditText?
SweetWisher ツ

2
El escenario es: tengo un diseño que contiene texto de edición, diseño relativo, ruleta y vista de lista. Quiero disparar el evento táctil del diseño principal cada vez que toco en cualquier lugar de la pantalla, excepto el texto de edición y la ruleta
SweetWisher ツ

9
Algo importante a tener en cuenta es que si usas TextView#setOnClickListener()en el TextView, se puede hacer clic, incluso si se declara como android:clickable="false", e incluso si el ClickListenerestá configurado en null( setOnclickListener(null))
Christian García

3
Dato curioso: si en TextView hay un android:inputTypeatributo, consumirá silenciosamente los eventos de clic incluso con clickable: false y focusable: false; en mi caso estaba ambientado en un estilo y me costó 30 minutos descubrir la causa.
Kirill Karmazin

18

A veces, solo esto ayuda:

View child = parent.findViewById(R.id.btnMoreText);
    child.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            View parent = (View) v.getParent();
            parent.performClick();
        }
    });

Otra variante, no siempre funciona:

child.setOnClickListener(null);

Esto funcionó CardViewcomo vista secundaria, ya que CardViewparece ignorar clickable="false"y focusable="false". Sin embargo, usar setOnTouchListenery llamar onTouchEvental padre le permite al padre mostrar retroalimentación táctil (por ejemplo, efecto dominó).
firma del método

Publiqué el código relevante a continuación: stackoverflow.com/a/52928884/5652513 .
firma del método

10

Poner

android:duplicateParentState="true"

en child, las vistas obtienen su estado dibujable (enfocado, presionado, etc.) de su padre directo en lugar de sí mismo. puede configurar onclick para los padres y llamar al niño cuando se hace clic


OP quiere llamar al oyente de clics de los padres cuando se hace clic en el niño, no al contrario.
Farid

3

Si TextViewcrea problemas de clic, elimínelo android:inputType=""de su archivo xml.


Si no sabe por qué, le recomiendo que no lo haga. Solo digo ... a cada uno lo suyo.
dell116

Debes configurarlo enandroid:inputType="none"
AZ_

1

Esta respuesta es similar a la respuesta de Alexander Ukhov , excepto que usa eventos táctiles en lugar de eventos de clic. Estos eventos permiten que el padre muestre los estados de presión adecuados (por ejemplo, efecto dominó). Esta respuesta también está en Kotlin en lugar de Java.

view.setOnTouchListener { view, motionEvent ->
    (view.parent as View).onTouchEvent(motionEvent)
}

0

Si quieres tanto OnTouchy OnClickescucha para padres e hijos vista tanto, por favor utilice a continuación truco:

  1. El usuario ScrollView como una vista principal y dentro de eso colocó su vista secundaria dentro de Relative / LinearLayout.

  2. Haga que Parent ScrollView android:fillViewport="true"no se desplace por View.

  3. A continuación, configure el OnTouchoyente como padre y el OnClickoyente como vistas secundarias. Y disfruta de las devoluciones de llamada de ambos oyentes.

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.