Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Based on answers from post [#937313][1] (thanks go to gav and paiego), I whipped up the following code to recognize simple gestures (horizontal swipes) on ListView. </p> <p>However, after a fling operation, the ListView's <code>onItemClick()</code> listener will be called too! Therefore, you end up with a fling and an extra onItemClick(). I think this is because Android sends an item-click event on every button-up, no matter how far way the user has moved his finger. To remedy this, instead of registering a usual <code>OnItemClickListener()</code>, I provided my own method <code>myOnItemClick()</code>. Then I override the <code>SimpleOnGestureListener.onSingleTapUp()</code> method, so that when the finger is up, this method will call myOnItemClick() manually. </p> <p>So far this method works fine for me. No complaints :-).</p> <pre><code>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&lt;String&gt;(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&lt;?&gt; 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()) &gt; REL_SWIPE_MAX_OFF_PATH) return false; if(e1.getX() - e2.getX() &gt; REL_SWIPE_MIN_DISTANCE &amp;&amp; Math.abs(velocityX) &gt; REL_SWIPE_THRESHOLD_VELOCITY) { onRTLFling(); } else if (e2.getX() - e1.getX() &gt; REL_SWIPE_MIN_DISTANCE &amp;&amp; Math.abs(velocityX) &gt; 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" }; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload