Detección de gestos de lanzamiento en diseño de cuadrícula

Resuelto gav asked hace 54 años • 18 respuestas

Quiero que flingla detección de gestos funcione en mi aplicación de Android.

Lo que tengo es uno GridLayoutque contiene 9 ImageViews. La fuente se puede encontrar aquí: Diseño de cuadrícula de Romain Guys .

Ese archivo que tomé es de la aplicación Photostream de Romain Guy y solo ha sido ligeramente adaptado.

Para la situación de un simple clic, solo necesito configurar onClickListenerpara cada uno ImageViewque agrego que sea el principal activityque implementa View.OnClickListener. Parece infinitamente más complicado implementar algo que reconozca un archivo fling. ¿Supongo que esto se debe a que puede extenderse views?

  • Si mi actividad se implementa, OnGestureListenerno sé cómo configurarla como detector de gestos para las Gridvistas Imageque agrego.

    public class SelectFilterActivity extends Activity implements
       View.OnClickListener, OnGestureListener { ...
    
  • Si mi actividad se implementa, OnTouchListenerentonces no tengo ningún onFlingmétodo para hacerlo override(tiene dos eventos como parámetros que me permiten determinar si la aventura fue digna de mención).

    public class SelectFilterActivity extends Activity implements
        View.OnClickListener, OnTouchListener { ...
    
  • Si hago una costumbre View, como GestureImageViewesa se extiende, ImageViewno sé cómo saber la actividad que flingha ocurrido desde la vista. En cualquier caso, probé esto y no se llamaron los métodos cuando toqué la pantalla.

Realmente solo necesito un ejemplo concreto de cómo funciona esto en todas las vistas. ¿Qué, cuándo y cómo debo adjuntar esto listener? También necesito poder detectar clics únicos.

// Gesture detection
mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {

    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        int dx = (int) (e2.getX() - e1.getX());
        // don't accept the fling if it's too short
        // as it may conflict with a button push
        if (Math.abs(dx) > MAJOR_MOVE && Math.abs(velocityX) > Math.absvelocityY)) {
            if (velocityX > 0) {
                moveRight();
            } else {
                moveLeft();
            }
            return true;
        } else {
            return false;
        }
    }
});

¿Es posible colocar una vista transparente en la parte superior de mi pantalla para capturar aventuras?

Si elijo no mostrar inflatemis vistas de imágenes secundarias desde XML, ¿puedo pasarlas GestureDetectorcomo parámetro de constructor a una nueva subclase que ImageViewcreo?

Esta es la actividad muy simple para la que estoy intentando que flingfuncione la detección: SelectFilterActivity (adaptado de photostream) .

He estado mirando estas fuentes:

  • Detectar gestos - Tutorial

  • Documentos SDK

  • Código de calculadora

Nada me ha funcionado hasta ahora y esperaba algunos consejos.

gav avatar Jan 01 '70 08:01 gav
Aceptado

Gracias a Code Shogun , cuyo código adapté a mi situación.

Deje que su actividad se implemente OnClickListenercomo de costumbre:

public class SelectFilterActivity extends Activity implements OnClickListener {

  private static final int SWIPE_MIN_DISTANCE = 120;
  private static final int SWIPE_MAX_OFF_PATH = 250;
  private static final int SWIPE_THRESHOLD_VELOCITY = 200;
  private GestureDetector gestureDetector;
  View.OnTouchListener gestureListener;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    /* ... */

    // Gesture detection
    gestureDetector = new GestureDetector(this, new MyGestureDetector());
    gestureListener = new View.OnTouchListener() {
      public boolean onTouch(View v, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
      }
    };

  }

  class MyGestureDetector extends SimpleOnGestureListener {
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
      try {
        if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
          return false;
        // right to left swipe
        if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
          Toast.makeText(SelectFilterActivity.this, "Left Swipe", Toast.LENGTH_SHORT).show();
        } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
          Toast.makeText(SelectFilterActivity.this, "Right Swipe", Toast.LENGTH_SHORT).show();
        }
      } catch (Exception e) {
         // nothing
      }
      return false;
    }

    @Override
    public boolean onDown(MotionEvent e) {
      return true;
    }
  }
}

Adjunte su detector de gestos a todas las vistas que agregue al diseño principal;

// Do this for each view added to the grid
imageView.setOnClickListener(SelectFilterActivity.this); 
imageView.setOnTouchListener(gestureListener);

Observe con asombro cómo se ven afectados sus métodos anulados, tanto los onClick(View v)de la actividad como los onFlingdel gesto oyente.

public void onClick(View v) {
  Filter f = (Filter) v.getTag();
  FilterFullscreenActivity.show(this, input, f);
}

El baile posterior a la aventura es opcional pero recomendable.

gav avatar Jun 02 '2009 09:06 gav

Una de las respuestas anteriores menciona el manejo de diferentes densidades de píxeles, pero sugiere calcular los parámetros de deslizamiento manualmente. Vale la pena señalar que en realidad puedes obtener valores escalados y razonables del sistema usando ViewConfigurationla clase:

final ViewConfiguration vc = ViewConfiguration.get(getContext());
final int swipeMinDistance = vc.getScaledPagingTouchSlop();
final int swipeThresholdVelocity = vc.getScaledMinimumFlingVelocity();
final int swipeMaxOffPath = vc.getScaledTouchSlop();
// (there is also vc.getScaledMaximumFlingVelocity() one could check against)

Noté que el uso de estos valores hace que la "sensación" de lanzar sea más consistente entre la aplicación y el resto del sistema.

Xion avatar Apr 20 '2011 17:04 Xion