2010-10-13 12 views
13

Hallo ich muss eine Geste zu meinem Listview hinzufügen, ich möchte die gleiche Funktionalität der Kontaktanwendung zu implementieren. wenn ich links wischen sollte es eine Nachricht senden, rechts swipe es sollte anrufen. kann jemand mir helfen, wie man diese Gestenerkennung macht ... ich habe es in verschiedenen anderen Ansichten implementiert ... aber ich konnte nicht für ListView tun ... ich gehe nicht was geht worng ... mein Code ist `Geste in 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

möglich Duplikat [wie zu implementieren fling in android listview] (http://stackoverflow.com/questions/4030389/how-to-implement-fling-in-android-listview) –

Antwort

46

Basierend auf den Antworten von post [# 937313] [1] (dank an gav und paiego), Schlag ich den folgenden Code bis zu einfachen Gesten (horizontal klaut) auf Listview zu erkennen.

Nach einem Fling-Vorgang wird der ListView-Listener onItemClick() aufgerufen! Daher enden Sie mit einem Fling und einem zusätzlichen onItemClick(). Ich denke, das liegt daran, dass Android bei jedem Buttonup ein Item-Click-Ereignis sendet, egal wie weit der Benutzer seinen Finger bewegt hat. Um dies zu beheben, habe ich statt einer üblichen OnItemClickListener() meine eigene Methode myOnItemClick() zur Verfügung gestellt. Dann überschreibe ich die SimpleOnGestureListener.onSingleTapUp() Methode, so dass, wenn der Finger oben ist, diese Methode myOnItemClick() manuell aufrufen wird.

Bis jetzt funktioniert diese Methode gut für mich. Keine Beschwerden :-).

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

danke für die teilen :-) – Ads

+0

nice one. Vielen Dank. – dierre

+0

@wwyt, funktioniert wie ein Charme! Danke Freund aber gibt es einen Weg, ohne ListActivity zu erweitern? weil ich eine andere Klasse erweitern muss –

2

--Edited --- Wenn Sie hier von Google kam, möchte nur sagen, dass, obwohl diese Lösung funktioniert immer noch, dass bestimmte Konstruktor GestureDetector veraltet.

Wenn Sie Swipe-Gesten auf Ihrem Android-App implementieren möchten können Sie diese Bibliothek in Betracht ziehen: https://github.com/liuzc/android-swipelistview

Oder diese (klaut funktionieren wie gmail): https://github.com/nhaarman/ListViewAnimations

+0

Diese Aussage ist falsch. Bitte lesen Sie die Dokumentation, die Sie verlinkt haben. – carlrice

+0

danke man hat es gerade bearbeitet – golfadas

+1

ersten Link funktioniert nicht mehr, vielleicht meintest du das https://github.com/liuzc/android-swipelistview – Mitro