Pasar evento de clic a través de la vista android

Tengo la disposición del marco:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="10dp" > <LinearLayout android:id="@+id/widgetView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:layout_margin="10dp" android:gravity="center" > </LinearLayout> <LinearLayout android:id="@+id/widgetOverlayFrame" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="false" > </LinearLayout> 

El primer diseño contiene la disposición del widget, y el segundo es transparente y recibe onLongClick para el método de arrastrar. Eso funciona, el problema es cuando quiero interactuar con un widget, hacer clic en algo, hacer clic en evento es tomado por overlayFrame. ¿Cómo puedo pasar clic evento superpuesto overlayFrame a widgetView?

EDITAR:

Ahora estoy tratando de adjuntar GestureLister a overlayFrame LinearLayout, para ver de alguna manera la diferencia entre MotionEvent que representan un solo clic y un clic largo. El problema que estoy enfrentando es que OnLongPress en el oyente gesto siempre se llama lo que hago, haga clic en un solo clic o largo.

¿Hay una explicación para este comportamiento? Tnx!

En lugar de utilizar GestureListener puede anular el onTouchListener de esta manera.

Esto llamará longPress cuando el temporizador se agota y si un up se interpone cancelará el LongPress

  CountDownTimer c; long time=5000; @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: c= new CountDownTimer(5000, 1000) { public void onTick(long millisUntilFinished) { time=millisUntilFinished; } public void onFinish() { Log.i("","LONG PRESS"); }}.start(); break; case MotionEvent.ACTION_UP: if (time>0) { Log.i("example","short click"); c.cancel(); } break; } return true; } 

Tal vez establecer el atributo de la superposición android:focusable="false" o android:focusableInTouchMode="false" sería suficiente.

También puede crear su propio widget de superposición y reemplazar su método onInterceptTouchEvent para devolver siempre false.

 public class NotTouchableLinearLayout extends LinearLayout { // Override constructors // ... @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return false; } } 

En lugar de configurar un GestureListener en el diseño superior, debe crear su propia clase que extienda LinearLayout y reemplazar su método onTouchEvent . Allí se puede implementar la lógica de clic largo \ clic corto, etc.

Los eventos de clic primero se enviarán al diseño del widget y solo si no los maneja (de ahí que sea onTouchEvent devuelve false ), los obtendrá en el diseño superior.

editar:

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="10dp" > <LinearLayout android:id="@+id/widgetView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:layout_margin="10dp" android:gravity="center" > </LinearLayout> <com.example.touchtesting.MyLinearLayout android:id="@+id/widgetOverlayFrame" android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="false" > </com.example.touchtesting.MyLinearLayout> </FrameLayout> 

Cambie el com.example.touchtesting al nombre de su paquete. Y esta es la clase:

  public class MyLinearLayout extends LinearLayout{ public MyLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); } private long startClick = 0; @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: startClick = ev.getEventTime(); break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: if (ev.getEventTime() - startClick < 500) { Log.i("example","short click"); } else { Log.i("example","long click"); } break; } return true; } } 

Para obtener los clics largos para pasar a través de la widgetView LinearLayout añadir android:longClickable="true" . (Para clics ordinarios, añada android:clickable="true" )

Así que widgetView se convierte en:

 <LinearLayout android:id="@+id/widgetView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:layout_margin="10dp" android:gravity="center" android:longClickable="true"> </LinearLayout> 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.