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


Manejo simultáneo de eventos táctiles en varias vistas en Android

Teniendo en cuenta el ejemplo de la imagen de abajo,

Introduzca aquí la descripción de la imagen

Estoy buscando una solución para pasar los eventos de toque de la vista de lienzo a la Viewpager . Esto es necesario para aplicar la misma cantidad de zoom en ambas vistas al mismo tiempo.

Aquí está la descripción técnica de lo que está pasando,

(Consideremos la vista como A , B y C )

A. Vista de los Padres

B. Ver

C. Ver buscapersonas

Antes de que se envíe a dispatchTouchEvent () a los niños ( B & C ), el A.dispatchTouchEvent () llamará primero A.onInterceptTouchEvent () para ver si el grupo de vistas está interesado en interceptar el evento.

Así que si A.onTouchEvent () devuelve false , entonces regresa a B.onTouchEvent () . Si eso devuelve false entonces regresa a C.onTouchEvent () y el despacho continúa como de costumbre.

Y al volver verdad ,

  1. ACTION_CANCEL se enviará a todos los niños.

  2. Todos los eventos de gestos posteriores (hasta ACTION_UP / ACTION_CANCEL ) serán consumidos por los oyentes de eventos ( OnTouchListener.onTouch () ) si se definen, de lo contrario el manejador de eventos A.onTouchEvent () en el nivel de A.

En este punto puedo pasar los eventos de los padres a las vistas de los niños, pero no puedo dejar que la vista de 2 niños B. & C maneja los eventos juntos (aplicando la misma cantidad de zoom en ambas vistas).

¿Hay alguna forma de pasar los eventos táctiles de la vista padre a un niño uno para que puedan procesar los eventos simultáneamente?

Aquí está mi configuración de diseño,

<RelativeLayout android:id="@+id/layoutParent" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#FFFFFFFF"> <com.androidapp.NonSwipeableViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:background="@color/transparent" /> <com.androidapp.DrawingView android:id="@+id/drawing" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/transparent" /> </RelativeLayout> 

  • ¿Por qué mi menú de edición / copia de EditText se encuentra debajo de EditText? ¿Cómo cambiar el orden z de la ventana emergente?
  • ¿Cómo referenciar un control de otro durante la inflación?
  • Vista web de Android: lee las cookies
  • ¿Qué hace exactamente offsetLeftAndRight ()?
  • ¿Hay una manera de localizar de forma programática todas las ventanas dentro de una aplicación determinada?
  • EditText no desplazable dentro de ScrollView
  • Android: LinearLayout addView Animación
  • Reproducción de un video local de aplicación (.mp4) en una vista web
  • 2 Solutions collect form web for “Manejo simultáneo de eventos táctiles en varias vistas en Android”

    Si no estoy equivocado, desea procesar el mismo evento táctil tanto en la vista superior como en la inferior. De acuerdo con la arquitectura de Android touch, no puede manejar eventos táctiles desde varias vistas al mismo tiempo. Tienes que procesarlo dentro del método onTouchEvent() o pasar a la siguiente vista. También debe esperar hasta que la vista superior finalice el procesamiento de MotionEvent( ) y permita que la vista secundaria sea MotionEvent( .

    Aquí está una solución posible usando el acercamiento de RxAndroid ,

    Dentro de MotionEvent() su vista de lienzo,

     @Override public boolean onTouchEvent(MotionEvent event) { // process all touch events (UP/DOWN/MOVE) //send events as observable RxBus.getInstance().sendMotionEvent(event); return true; } 

    Esto observará los eventos de movimiento y notificará a todos los observadores.

    Ahora, dentro del onResume() su viewpager, suscríbase para los eventos de movimiento de manera que cada vez que se haga un cambio desde el lienzo, pasará inmediatamente los eventos.

     Subscription RxBus _rxBus = RxBus.getInstance(); subscription = _rxBus.getMotionEvent() .subscribe(new Action1<MotionEvent>() { @Override public void call(MotionEvent event) { // call the onTouchEvent of your widget eg ImageView and pass the received event // this will apply the same touch event that was applied in the canvas // .onTouchEvent(event) is important to override the onTouchEvent() of your widget that will use the touch event imageView.onTouchEvent(event); } }); 

    La clase RxBus se da a continuación,

     public class RxBus { private static RxBus instance; private final PublishSubject<MotionEvent> motion_event = PublishSubject.create(); public static RxBus getInstance() { if (instance == null) { instance = new RxBus(); } return instance; } public void sendMotionEvent(MotionEvent motionEvent) { motion_event.onNext(motion_event); } public Observable<MotionEvent> getMotionEvent() { return motion_event; } } 

    Es bastante fácil de implementar mediante el uso de devolución de llamada. Basta con crear una interfaz con cualquier método, que necesita y luego implementar en su Viewpager. La llamada se invocará en la clase Ver basada en sus eventos de toque y responderá a Viewpager. He creado un ejemplo con un ImageView en mi MainActivity y llamado a cambiar su tamaño de un fragmento diferente y funciona. Aquí está mi código de abajo:

     public interface ICallBackForResize { void resizeme(); void actionUp(); void actionDown(); } 

    Actividad principal:

     public class MainActivity extends AppCompatActivity implements ICallBackForResize { ImageView img; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); img= (ImageView) findViewById(R.id.image); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } @Override public void resizeme() { Toast.makeText(MainActivity.this,"called",Toast.LENGTH_LONG).show(); img.getLayoutParams().height += 20; img.getLayoutParams().width += 20; img.requestLayout(); } @Override public void actionUp() { //do whatever } @Override public void actionDown() { //do whatever } } 

    Mi clase Fragment con un simple botón:

     public class MyFragmentButton extends Fragment { View view; ICallBackForResize callBackForResize; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); callBackForResize= (ICallBackForResize) getActivity(); } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { view=inflater.inflate(R.layout.mybutton,container,false); Button btn= (Button) view.findViewById(R.id.button); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { callBackForResize.resizeme(); } }); return view; } } 

    Creo que usted no necesita el archivo xml. Acabo de compartir si alguien necesita:

    Activity_main:

     <?xml version="1.0" encoding="utf-8"?> 

     <android.support.design.widget.AppBarLayout android:layout_height="wrap_content" android:layout_width="match_parent" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" /> </android.support.design.widget.AppBarLayout> <include layout="@layout/content_main"/> </android.support.design.widget.CoordinatorLayout> 

    Content_main:

     <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:showIn="@layout/activity_main" tools:context="nanofaroque.com.addlistener.MainActivity"> <ImageView android:id="@+id/image" android:text="Hello World!" android:layout_width="100dp" android:layout_gravity="center" android:src="@mipmap/ic_launcher" android:layout_height="100dp" /> <fragment android:name="nanofaroque.com.addlistener.MyFragmentButton" android:id="@+id/headlines_fragment" android:layout_width="100dp" android:layout_height="100dp" /> </FrameLayout> 

    Mi botón

      <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.