you tube studio pro multi down android touch

tube - Android SimpleOnGestureListener.onFling obtiene un MotionEvent nulo



touch events android (6)

Estoy intentando detectar un evento de lanzamiento en una aplicación de Android simple, pero el primer argumento de MotionEvent siempre es nulo. ¿Por qué se llama al método onFling con un argumento nulo? La documentación de Android dice que se llama cuando ocurre un evento de lanzamiento con la inicial abajo en MotionEvent y la coincidencia con MotionEvent.

class MyGestureDetector extends SimpleOnGestureListener { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // e1 always == null, return early a null reference exception if (e1 == null) { return false; } if (e1.getY() - e2.getY() > 120) { handleFlingEvent(); return true; } return false; } }

La actividad principal tiene este método onTouchEvent:

GestureDetector flingDetector = new GestureDetector(new MyGestureDetector()); @Override public boolean onTouchEvent(MotionEvent event) { if (flingDetector.onTouchEvent(event)) { return true; } return super.onTouchEvent(event); }


Creo que el evento onDown ha sido reanudado por la vista de desplazamiento, por lo que no podemos obtener el evento en la actividad. Si personaliza un ScrollView y anula el dispatchTouchEvent () y onTouchEvent (), el problema se resolverá.

Actividad:

public class TestActivity extends Activity { private MyScrollView scrollView; private TestActivity me; private GestureDetector detector; protected void onCreate(Bundle savedInstanceState) { this.me = this; MySimpleGestureListener gestureListener = new MySimpleGestureListener(); this.detector = new GestureDetector(gestureListener); this.scrollView.setOnTouchListener(onTouchListerner); this.scrollView.setDetector(detector); } private View.OnTouchListener onTouchListener = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return me.detector.onTouchEvent(event); } }; }

MySimpleGestureListener:

public class MySimpleGestureListener extends SimpleOnGestureListener { @Override public boolean onSingleTapUp(MotionEvent e) { return false; } @Override public void onShowPress(MotionEvent e) { } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return super.onScroll(e1, e2, distanceX, distanceY); } @Override public void onLongPress(MotionEvent e) { } @Override public boolean onDown(MotionEvent e) { return false; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // TODO do your onFling here } }

Por fin, MyScrollView

public class MyScrollView extends ScrollView { private GestureDetector detector; @Override public boolean dispatchTouchEvent(MotionEvent ev){ if (this.detector!= null) { detector.onTouchEvent(ev); super.dispatchTouchEvent(ev); return true; } return super.dispatchTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent ev) { super.onTouchEvent(ev); // if (this.detector != null) { return this.detector.onTouchEvent(ev); } return false; } // here is the getter and setter }

Espero que esto ayude.


En la clase de grupo de vista personalizada, necesita anular 2 métodos: onInterceptTouchEvent y onTouchEvent . Después de eso, debe llamar a GestureDetector.onTouchEvent() en ambos métodos. El evento ACTION_DOWN se pasa solo a onInterceptTouchEvent .

@Override public boolean onInterceptTouchEvent(MotionEvent event) { if(mDetector.onTouchEvent(event)) { return true; } return super.onInterceptTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { if(mDetector.onTouchEvent(event)) { return true; } return super.onTouchEvent(event); }


Primero encontré este problema con Android 4.0 ya que mi código funciona bien en todas las versiones anteriores. Después de seguir el ejemplo de las sugerencias, he encontrado que una solución alternativa es simplemente hacer un seguimiento del evento onDown y usarlo en lugar del primer parámetro de onFling en caso de que sea nulo.

public class MySimpleGestureListener extends SimpleOnGestureListener { protected MotionEvent mLastOnDownEvent = null; @Override public boolean onDown(MotionEvent e) { mLastOnDownEvent = e; return true;//super.onDown(e); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (e1==null) e1 = mLastOnDownEvent; if (e1==null || e2==null) return false; float dX = e2.getX()-e1.getX(); float dY = e2.getY()-e1.getY(); ...rest of code } ...rest of class }


Tenía 3 botones en diseño lineal horizontal y este diseño, a su vez, estaba rodeado de vista horizontalscrollview .

Luego puse simplegesturelistener en la vista simplegesturelistener horizontalscrollview y obtuve el mismo error que el anterior. Luego también simplegesturelistener para todos los botones en el diseño y funcionó.



Tengo el problema similar. Ocurre cuando el GestureDetector y el método onFling estaban en una clase de vista personalizada, que forma parte de la IU de la actividad. Después de una serie de pruebas, descubrí que solo la Actividad principal puede detectar bien el gesto de deslizar. Entonces resuelvo el problema reemplazándolos en la actividad. Pero no encontré la causa raíz de este problema.