Gesture in listview android

前端 未结 2 795
傲寒
傲寒 2020-12-01 00:22

hi i have to add a gesture to my listview,i want to implement the same functionality of contact application. when i left swipe it should send a message,right swipe it should

相关标签:
2条回答
  • 2020-12-01 00:59

    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.

    However, after a fling operation, the ListView's onItemClick() 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 OnItemClickListener(), I provided my own method myOnItemClick(). Then I override the SimpleOnGestureListener.onSingleTapUp() method, so that when the finger is up, this method will call myOnItemClick() manually.

    So far this method works fine for me. No complaints :-).

    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"
        };
    }
    
    0 讨论(0)
  • 2020-12-01 01:11

    --Edited--- If you came here from google, just want to tell you that although this solution still works, that specific constructor of GestureDetector is deprecated.

    If you want to implement swipe gestures on your android app you could consider using this library: https://github.com/liuzc/android-swipelistview

    Or this one (swipes work just like gmail): https://github.com/nhaarman/ListViewAnimations

    0 讨论(0)
提交回复
热议问题