Swipe Gesture inside ListView - Android [closed]
Asked Answered
M

2

1

I am a newbie for Android. I got a tutorial on how to implement the `listView here:

I implemented it and it is working fine. I need to implement a ViewSwitcher for the same. Like when I swipe the song, I need to get some options like play, add to queue etc.,

Pls go through that tutorial and pls help. I'm struggling almost from 3 weeks.

Hope someone will help me.

Edit 1: The below code is the main Activity:

import java.util.ArrayList;
import java.util.HashMap;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.widget.ViewSwitcher;

public class CustomizedListView extends Activity implements OnGestureListener{
// All static variables
static final String URL = "http://api.androidhive.info/music/music.xml";
// XML node keys
static final String KEY_SONG = "song"; // parent node
static final String KEY_ID = "id";
static final String KEY_TITLE = "title";
static final String KEY_ARTIST = "artist";
static final String KEY_DURATION = "duration";
static final String KEY_THUMB_URL = "thumb_url";


private ViewSwitcher switcher1;
private GestureDetector gesturedetector = null;
ListView list;
LazyAdapter adapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();

    XMLParser parser = new XMLParser();
    String xml = parser.getXmlFromUrl(URL); // getting XML from URL
    Document doc = parser.getDomElement(xml); // getting DOM element

    NodeList nl = doc.getElementsByTagName(KEY_SONG);
    // looping through all song nodes <song>
    for (int i = 0; i < nl.getLength(); i++) {
        // creating new HashMap
        HashMap<String, String> map = new HashMap<String, String>();
        Element e = (Element) nl.item(i);
        // adding each child node to HashMap key => value
        map.put(KEY_ID, parser.getValue(e, KEY_ID));
        map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
        map.put(KEY_ARTIST, parser.getValue(e, KEY_ARTIST));
        map.put(KEY_DURATION, parser.getValue(e, KEY_DURATION));
        map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL));

        // adding HashList to ArrayList
        songsList.add(map);

    }


    list=(ListView)findViewById(R.id.list);

    // Getting adapter by passing xml data ArrayList
    adapter=new LazyAdapter(this, songsList);        
    list.setAdapter(adapter);


    // Click event for single list row
    list.setOnItemClickListener(new OnItemClickListener() {

        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {


        }
    });



}   


@Override
public boolean onTouchEvent(MotionEvent event) {
        return gesturedetector.onTouchEvent(event);
}

public boolean onDown(MotionEvent e) {
    // TODO Auto-generated method stub
    return false;
}
int SWIPE_MIN_VELOCITY = 100;
int SWIPE_MIN_DISTANCE = 100;
//Sự kiện khi bạn vuốt màn hình đưa sang một bên nào đó

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY) {
    //Get Position
    float ev1X = e1.getX();
    float ev2X = e2.getX();

    //Get distance of X (e1) to X (e2)
    final float xdistance = Math.abs(ev1X - ev2X);
    //Get veclocity of cusor
    //Vận tốc = số điểm ảnh (px) / giây
   final float xvelocity = Math.abs(velocityX);

   //Vận tốc chuyển đổi X > 100 và khoảng cách từ điểm kéo đầu đến điểm kéo cuối > 100
   if( (xvelocity > SWIPE_MIN_VELOCITY) && (xdistance > SWIPE_MIN_DISTANCE) )
   {
        if(ev1X > ev2X)//Switch Left
        {
            previousView();
        }
        else//Switch Right
        {
            nextView();
        }
   }

    return false;
}

public void onLongPress(MotionEvent e) {

}

public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,float distanceY) {
    return false;
}

public void onShowPress(MotionEvent e) {

}

public boolean onSingleTapUp(MotionEvent e) {
    return false;
}

//Next, Previous Views
private void previousView() {
    switcher1.showPrevious();
}
private void nextView() {
    switcher1.showNext();
}

Below code the XML file.

<?xml version="1.0" encoding="utf-8"?>
  <ViewSwitcher xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/viewSwitcher1"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_alignParentLeft="true"
     android:layout_alignParentTop="true" >

   <include
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     layout="@layout/list_row_main" />

   <include
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     layout="@layout/list_row_swipe" />

</ViewSwitcher>
Mightily answered 25/7, 2012 at 10:1 Comment(7)
what is it that you are not understanding?Oozy
Hey Praveen ! Welcome to SO. You have come up with a nice app idea. Share with us some code what you have written or at what point you failed to achieve it. Everyone is here to help you.Happy Coding :)Conservatoire
I tried implementing. but the problem is Swipe action is not working. I tried onFling. its not working..Mightily
Welcome Praveen to SO. For your requirement, what if you display Quick actionFrisket
@PareshMayani, Thank you. But the client requirement is that they need the swipe to show more options.Mightily
@praveenkumar I am sure you are trying to implement this and For this you can check thisFrisket
@PareshMayani exact, But where can I get the source code of that twitter app ? I couldn't find any link.Mightily
G
6

As I understand your question, your problem is to detect the touch gesture within the ListView, right?

Therefore, you have to extend the ListView and detect horizontal touch gestures in the onInterceptTouchEvent method.

Heres is an example of a ListView, which does not react horizontally touch events. These events will be dispatched to you child view, which is in fact your list item view that has to catch these events (use gesture listener) and trigger the ViewSwitcher.

public class SampleListView extends ListView {

.
.
.

@Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                // reset difference values
                mDiffX = 0;
                mDiffY = 0;

                mLastX = ev.getX();
                mLastY = ev.getY();
                break;

            case MotionEvent.ACTION_MOVE:
                final float curX = ev.getX();
                final float curY = ev.getY();
                mDiffX += Math.abs(curX - mLastX);
                mDiffY += Math.abs(curY - mLastY);
                mLastX = curX;
                mLastY = curY;

                // don't intercept event, when user tries to scroll vertically
                if (mDiffX > mDiffY) {
                    return false; // do not react to horizontal touch events, these events will be passed to your list item view
                }
        }

        return super.onInterceptTouchEvent(ev);
    }

.
.
.

}
Gamb answered 25/7, 2012 at 10:8 Comment(4)
Yes, exactly.. I need to make the touch gesture work inside the ListView.Mightily
I've added some example code. let me know, if there is still something unclear.Gamb
@praveen kumar, hey if AZ13's solution is working then please mark it as a right answer, else comment here, it will be great help for others. Thanks !Dally
No, Its not working for me and We dropped the project too.Mightily
K
0

You can use motionevent to do it. You just need to trace the velocity.

for Example.

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
        float velocityY) {
    // TODO Auto-generated method stub
       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) {                  
              Toast.makeText(getApplicationContext(), "Left Swipe", 
              Toast.LENGTH_SHORT).show();                  
            } 
Kiblah answered 25/7, 2012 at 10:10 Comment(1)
I have tried this, pls see my question, but the gesture itself is not working.Mightily

© 2022 - 2024 — McMap. All rights reserved.