2010-10-13 22 views
13

hola tengo que agregar un gesto a mi lista de lista, quiero implementar la misma funcionalidad de la aplicación de contacto. cuando dejé de deslizar debería enviar un mensaje, deslice el dedo hacia la derecha y debería llamar. ¿Alguien puede ayudarme a hacer esa detección de gestos? Lo he implementado en varias otras vistas ... pero no pude hacer para listView ... no lo que voy a worng ... mi código es`Gesto en listview android

/** Called when the activity is first created. */ 
public void onCreate(Bundle icicle) { 
    super.onCreate(icicle); 
    setContentView(R.layout.main); 
    // Create an array of Strings, that will be put to our ListActivity 
    String[] names = new String[] { "Linux", "Windows7", "Eclipse", "Suse", "Ubuntu", "Solaris", "Android", "iPhone"}; 
    // Create an ArrayAdapter, that will actually make the Strings above 
    // appear in the ListView 
    this.setListAdapter(new ArrayAdapter<String>(this, R.id.MyList, names)); 
    gestureListener = new ListView.OnTouchListener() { 
     public boolean onTouch(View v, MotionEvent event) { 
      if (gestureDetector.onTouchEvent(event)) { 
       return true; 
      } 
      return false; 
     } 
    };  
} 

@Override 
protected void onListItemClick(ListView l, View v, int position, long id) { 
    super.onListItemClick(l, v, position, id); 
    // Get the item that was clicked 
    Object o = this.getListAdapter().getItem(position); 
    String keyword = o.toString(); 
    Toast.makeText(this, "You selected: " + keyword, Toast.LENGTH_LONG).show(); 
} 

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

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) { 
       Context ctx = getApplicationContext(); 
       CharSequence txt = "Right to Left Swipe"; 
       int duration = Toast.LENGTH_LONG; 
       Toast toast = Toast.makeText(ctx, txt, duration); 
       toast.show(); 
       Toast.makeText(this.getItem(lv.pointToPosition((int)e1.getX(),(int) e1.getY()))); 
       // return super.onFling();           
      } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
       Context ctx = getApplicationContext(); 
       CharSequence txt = "Left to Right Swipe"; 
       int duration = Toast.LENGTH_LONG; 
       Toast toast = Toast.makeText(ctx, txt, duration); 
       toast.show(); 
      } 
     } catch (Exception e) { 
      // nothing 
     } 
     return false; 
    } 
} 
+0

posible duplicado de [aventura cómo poner en práctica en la vista de lista de Android] (http://stackoverflow.com/questions/4030389/how-to-implement-fling-in-android-listview) –

Respuesta

46

sobre la base de las respuestas de mensaje [# 937313] [1] (agradecimiento a Gav y paiego), me prepararon rápidamente el siguiente código para reconocer gestos simples (golpes horizontales) en ListView.

Sin embargo, después de una operación arrojadiza, también se llamará al oyente ListView's onItemClick(). Por lo tanto, terminas con una aventura y un extra onItemClick(). Creo que esto se debe a que Android envía un evento de clic de elemento en cada botón, sin importar cuán lejos haya movido el dedo el usuario. Para remediar esto, en lugar de registrar un OnItemClickListener() habitual, proporcioné mi propio método myOnItemClick(). Luego anulo el método SimpleOnGestureListener.onSingleTapUp(), de modo que cuando el dedo esté hacia arriba, este método llame a myOnItemClick() manualmente.

Hasta ahora, este método funciona bien para mí. Sin quejas :-).

public class PracticeActivity extends ListActivity { 

    private int REL_SWIPE_MIN_DISTANCE; 
    private int REL_SWIPE_MAX_OFF_PATH; 
    private int REL_SWIPE_THRESHOLD_VELOCITY; 

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

     // As paiego pointed out, it's better to use density-aware measurements. 
     DisplayMetrics dm = getResources().getDisplayMetrics(); 
     REL_SWIPE_MIN_DISTANCE = (int)(120.0f * dm.densityDpi/160.0f + 0.5); 
     REL_SWIPE_MAX_OFF_PATH = (int)(250.0f * dm.densityDpi/160.0f + 0.5); 
     REL_SWIPE_THRESHOLD_VELOCITY = (int)(200.0f * dm.densityDpi/160.0f + 0.5); 

     ListView lv = getListView(); 
     lv.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, 
      m_Starbucks)); 

     final GestureDetector gestureDetector = new GestureDetector(new MyGestureDetector()); 
     View.OnTouchListener gestureListener = new View.OnTouchListener() { 
      public boolean onTouch(View v, MotionEvent event) { 
       return gestureDetector.onTouchEvent(event); 
      }}; 
     lv.setOnTouchListener(gestureListener); 

     // Long-click still works in the usual way. 
     lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { 
      public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { 
       String str = MessageFormat.format("Item long clicked = {0,number}", position); 
       Toast.makeText(PracticeActivity.this, str, Toast.LENGTH_SHORT).show(); 
       return true; 
      } 
     }); 
    } 

    // Do not use LitView.setOnItemClickListener(). Instead, I override 
    // SimpleOnGestureListener.onSingleTapUp() method, and it will call to this method when 
    // it detects a tap-up event. 
    private void myOnItemClick(int position) { 
     String str = MessageFormat.format("Item clicked = {0,number}", position); 
     Toast.makeText(this, str, Toast.LENGTH_SHORT).show(); 
    } 

    private void onLTRFling() { 
     Toast.makeText(this, "Left-to-right fling", Toast.LENGTH_SHORT).show(); 
    } 

    private void onRTLFling() { 
     Toast.makeText(this, "Right-to-left fling", Toast.LENGTH_SHORT).show(); 
    } 

    class MyGestureDetector extends SimpleOnGestureListener{ 

     // Detect a single-click and call my own handler. 
     @Override 
     public boolean onSingleTapUp(MotionEvent e) { 
      ListView lv = getListView(); 
      int pos = lv.pointToPosition((int)e.getX(), (int)e.getY()); 
      myOnItemClick(pos); 
      return false; 
     } 

     @Override 
     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
      if (Math.abs(e1.getY() - e2.getY()) > REL_SWIPE_MAX_OFF_PATH) 
       return false; 
      if(e1.getX() - e2.getX() > REL_SWIPE_MIN_DISTANCE && 
       Math.abs(velocityX) > REL_SWIPE_THRESHOLD_VELOCITY) { 
       onRTLFling(); 
      } else if (e2.getX() - e1.getX() > REL_SWIPE_MIN_DISTANCE && 
       Math.abs(velocityX) > REL_SWIPE_THRESHOLD_VELOCITY) { 
       onLTRFling(); 
      } 
      return false; 
     } 

    } 

    private static final String[] m_Starbucks = { 
     "Latte", "Cappuccino", "Caramel Macchiato", "Americano", "Mocha", "White Mocha", 
     "Mocha Valencia", "Cinnamon Spice Mocha", "Toffee Nut Latte", "Espresso", 
     "Espresso Macchiato", "Espresso Con Panna" 
    }; 
} 
+1

gracias por compartir :-) – Ads

+0

nice one. Gracias. – dierre

+0

@wwyt, ¡funciona como un encanto! Gracias amigo pero, ¿hay alguna manera sin extender ListActivity? porque tengo que extender alguna otra clase –

2

--Edited --- Si usted vino aquí desde Google, sólo quiero decir que aunque esta solución todavía funciona, ese constructor específica de GestureDetector está en desuso.

Si desea implementar gestos banda magnética en su aplicación para Android que podría considerar el uso de esta biblioteca: https://github.com/liuzc/android-swipelistview

O ésta (golpes funcionan igual que Gmail): https://github.com/nhaarman/ListViewAnimations

+0

Esta declaración es incorrecta. Por favor, lea la documentación que ha vinculado. – carlrice

+0

gracias hombre solo lo editó – golfadas

+1

primer enlace ya no funciona, tal vez se refería a esto https://github.com/liuzc/android-swipelistview – Mitro