¿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?

shiami
fuente

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.

Luis Miguel Serrano
fuente
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 .

siyb
fuente
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);
Alexander Ukhov
fuente
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

Ahmad Ronagh
fuente
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.

Sanjay Chaudhary
fuente
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)
}
método firma
fuente
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.

Kishor Patil
fuente