2010-12-07 14 views
47

¿Alguien tiene un ejemplo simple de una ListActivity que muestra Textviews en una columna y cuando desliza de izquierda a derecha, ve esa fila en una nueva vista? Esto sería para editar los datos de esa fila o mostrar información más detallada en esa fila. No haga referencia al código shogun u otros sitios ya que he buscado en Google y no he visto esta respuesta.Android Swipe on List

+0

ya estoy usando contextual para cambiar los tamaños de fuente y por un LongPress para otras actividades. Quiero que el usuario pueda deslizar de izquierda a derecha para abrir la pantalla de datos completa de la fila en la que se movió. – JPM

+0

Creo que los fragmentos resuelven este problema ahora. – JPM

Respuesta

115

Tuve el mismo problema y no encontré mi respuesta aquí.

Quería detectar una acción deslizante en el elemento ListView y marcarlo como barrido, mientras continúo admitiendo OnItemClick y OnItemLongClick.

aquí soy yo solución:

primero La clase SwipeDetector:

import android.util.Log; 
import android.view.MotionEvent; 
import android.view.View; 

public class SwipeDetector implements View.OnTouchListener { 

    public static enum Action { 
     LR, // Left to Right 
     RL, // Right to Left 
     TB, // Top to bottom 
     BT, // Bottom to Top 
     None // when no action was detected 
    } 

    private static final String logTag = "SwipeDetector"; 
    private static final int MIN_DISTANCE = 100; 
    private float downX, downY, upX, upY; 
    private Action mSwipeDetected = Action.None; 

    public boolean swipeDetected() { 
     return mSwipeDetected != Action.None; 
    } 

    public Action getAction() { 
     return mSwipeDetected; 
    } 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      downX = event.getX(); 
      downY = event.getY(); 
      mSwipeDetected = Action.None; 
      return false; // allow other events like Click to be processed 
     case MotionEvent.ACTION_UP: 
      upX = event.getX(); 
      upY = event.getY(); 

      float deltaX = downX - upX; 
      float deltaY = downY - upY; 

      // horizontal swipe detection 
      if (Math.abs(deltaX) > MIN_DISTANCE) { 
       // left or right 
       if (deltaX < 0) { 
        Log.i(logTag, "Swipe Left to Right"); 
        mSwipeDetected = Action.LR; 
        return false; 
       } 
       if (deltaX > 0) { 
        Log.i(logTag, "Swipe Right to Left"); 
        mSwipeDetected = Action.RL; 
        return false; 
       } 
      } else if (Math.abs(deltaY) > MIN_DISTANCE) { // vertical swipe 
                  // detection 
       // top or down 
       if (deltaY < 0) { 
        Log.i(logTag, "Swipe Top to Bottom"); 
        mSwipeDetected = Action.TB; 
        return false; 
       } 
       if (deltaY > 0) { 
        Log.i(logTag, "Swipe Bottom to Top"); 
        mSwipeDetected = Action.BT; 
        return false; 
       } 
      } 
      return false; 
     } 
     return false; 
    } 
} 

segundo utilizo la clase detector de golpe en la vista de lista:

final ListView lv = getListView(); 
    final SwipeDetector swipeDetector = new SwipeDetector(); 
    lv.setOnTouchListener(swipeDetector); 
    lv.setOnItemClickListener(new OnItemClickListener() { 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       if (swipeDetector.swipeDetected()){ 
        // do the onSwipe action 
       } else { 
        // do the onItemClick action 
       } 
      } 
    }); 
    lv.setOnItemLongClickListener(new OnItemLongClickListener() { 
     @Override 
     public boolean onItemLongClick(AdapterView<?> parent, View view,int position, long id) { 
      if (swipeDetector.swipeDetected()){ 
       // do the onSwipe action 
      } else { 
       // do the onItemLongClick action 
      } 
     } 
    }); 

De esta manera puedo apoyar 3 acciones: deslizar, hacer clic, hacer clic largo y puedo usar la información del elemento ListView.

añadió más tarde:

Desde ListView coge una acción de desplazamiento, a veces es difícil de pasar el dedo. Para solucionarlo, hice el siguiente cambio en SwipeDetector.onTouch:

public boolean onTouch(View v, MotionEvent event) { 
    switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN: { 
      downX = event.getX(); 
      downY = event.getY(); 
      mSwipeDetected = Action.None; 
      return false; // allow other events like Click to be processed 
     } 
     case MotionEvent.ACTION_MOVE: { 
      upX = event.getX(); 
      upY = event.getY(); 

      float deltaX = downX - upX; 
      float deltaY = downY - upY; 

      // horizontal swipe detection 
      if (Math.abs(deltaX) > HORIZONTAL_MIN_DISTANCE) { 
       // left or right 
       if (deltaX < 0) { 
        Log.i(logTag, "Swipe Left to Right"); 
        mSwipeDetected = Action.LR; 
        return true; 
       } 
       if (deltaX > 0) { 
        Log.i(logTag, "Swipe Right to Left"); 
        mSwipeDetected = Action.RL; 
        return true; 
       } 
      } else 

      // vertical swipe detection 
      if (Math.abs(deltaY) > VERTICAL_MIN_DISTANCE) { 
       // top or down 
       if (deltaY < 0) { 
        Log.i(logTag, "Swipe Top to Bottom"); 
        mSwipeDetected = Action.TB; 
        return false; 
       } 
       if (deltaY > 0) { 
        Log.i(logTag, "Swipe Bottom to Top"); 
        mSwipeDetected = Action.BT; 
        return false; 
       } 
      } 
      return true; 
     } 
    } 
    return false; 
} 
+0

¿Por qué es que si hubiera regresado cierto otros eventos como Click no serían procesados? – prometheuspk

+0

@Pinhassi cuál será el valor para HORIZONTAL_MIN_DISTANCE y VERTICAL_MIN_DISTANCE – AndroidDev

+1

HORIZONTAL_MIN_DISTANCE y VERTICAL_MIN_DISTANCE son las distancias mínimas que el dedo del usuario debe mover para que la acción se considere un deslizamiento. Lo configuré en: HORIZONTAL_MIN_DISTANCE = 40; VERTICAL_MIN_DISTANCE = 80; –

1

aquí hay un fragmento que uso para detectar golpes. A continuación, puede usar un viewflipper para cambiar la vista.

@Override 
     public boolean onTouchEvent(MotionEvent event) { 
      if (gestureDetector.onTouchEvent(event)) { 
       return true; 
      } else { 
       return false; 
      } 
     } 

     private static final int SWIPE_MIN_DISTANCE = 30; 
     private static final int SWIPE_MAX_OFF_PATH = 250; 
     private static final int SWIPE_THRESHOLD_VELOCITY = 200; 
     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) { 
         leftFling(); 
        } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE 
          && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
         rightFling(); 
        } 
       } catch (Exception e) { 
        // nothing 
       } 
       return false; 
      } 

     } 
+0

Estaba buscando más un ejemplo prrof.He intentado con viewflippers pero siempre hay algo extraño con el tamaño de la lista cuando haces eso. Me gusta tu código, aunque está bastante limpio. Tendré que usarlo en mis futuros intentos, gracias – JPM

1

Aquí es una versión muy simplificada utilizando los dos oyentes (onTouch para la detección de golpe, y onClickIem para la detección elemento clic) usando la bandera a isSwipe detener la onClickItemListener hasta su confirmaron que es no era un golpe

Detectar el clic
teniendo en cuenta que no es un golpe primera

 listView.setOnItemClickListener(new OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) 
      { 
       if(!isSwipe) 
       { 
        adapter.increase(arg2); 
        adapter.notifyDataSetChanged(); 
       } 
      } 
     }); 

Detectando el golpe

 listView.setOnTouchListener(new OnTouchListener() { 
     private int action_down_x = 0; 
      private int action_up_x = 0; 
      private int difference = 0; 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 

       switch (event.getAction()) { 
        case MotionEvent.ACTION_DOWN: 
         action_down_x = (int) event.getX(); 
         isSwipe=false; //until now 
         break; 
        case MotionEvent.ACTION_MOVE: 
         if(!isSwipe) 
         { 
          action_up_x = (int) event.getX(); 
          difference = action_down_x - action_up_x; 
          if(Math.abs(difference)>50) 
          { 
           Log.d("action","action down x: "+action_down_x); 
           Log.d("action","action up x: "+action_up_x); 
           Log.d("action","difference: "+difference); 
           //swipe left or right 
           if(difference>0){ 
            //swipe left 
            Log.d("action","swipe left"); 
            adapter.decrease(selectedItem); 
            adapter.notifyDataSetChanged(); 
           } 
           else{ 
            //swipe right 
            Log.d("action","swipe right"); 
           } 
           isSwipe=true; 
          } 
         } 
         break; 
        case MotionEvent.ACTION_UP: 
         Log.d("action", "ACTION_UP - "); 
         action_down_x = 0; 
         action_up_x = 0; 
         difference = 0; 
         break; 
       } 
       return false; //to allow the clicklistener to work after 
      } 
     }) 
0

Si desea mostrar algunos botones con acciones cuando un elemento de la lista es deslizar una gran cantidad de bibliotecas en Internet que tiene este comportamiento. Implementé la biblioteca que encontré en Internet y estoy muy satisfecho. Es muy simple de usar y muy rápido. Mejoré la biblioteca original y agregué un nuevo oyente de clic para hacer clic en el elemento. También agregué la biblioteca impresionante de la fuente (http://fortawesome.github.io/Font-Awesome/) y ahora puedes simplemente agregar un nuevo título del artículo y especificar el nombre del icono de la fuente impresionante.

Here es el enlace github

Cuestiones relacionadas