Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android list view swipe right to reveal button

I wanted to achieve something like swipe right to reveal the button on each list view row in Android development.

I have a fully working list view which fetch and populate the data dynamically:

public class ProfilePastEvent extends Fragment{
View pastEventView;
Context context;
private ListView listview;
private ListAdapter mAdapter;
public ArrayList<Event> _eventlist = new ArrayList<Event>();
EventController eventCtrl = new EventController();

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    listview = (ListView) pastEventView
            .findViewById(R.id.pastEventListview);

    mAdapter = new ListAdapter(getActivity());
    listview.setAdapter(mAdapter);

    listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View item,
                int position, long id) {

    });
    return pastEventView;
}

private class ListAdapter extends BaseAdapter {
    LayoutInflater inflater;
    ViewHolder viewHolder;

    public ListAdapter(Context context) {
        inflater = LayoutInflater.from(context);
    }

    public int getCount() {
        return _eventlist.size();
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {

            convertView = inflater.inflate(
                    R.layout.profile_past_listview_row, null);
            viewHolder = new ViewHolder();

            viewHolder.txt_dpastEventName = (TextView) convertView
                    .findViewById(R.id.txtPastEventName);


            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.txt_dpastEventName.setText(_eventlist.get(position)
                .getEventName().trim());


        return convertView;
    }
}

private class ViewHolder {
    TextView txt_dpastEventName;
}
}

However, this list view works like user click on certain row to open up a new intent. How can I implement the swipe right to reveal 'View more' or 'Delete' button feature?

like image 669
BlackMamba Avatar asked Oct 16 '25 21:10

BlackMamba


2 Answers

You can use this library AndroidSwipeLayout. It has following type of animations:

enter image description here

OR

If you want to program this by your self, add following class. I've implemented this in one of the sample apps. I've found this on stackoverflow only, but don't remember from where.

public class MyGestureDetector extends SimpleOnGestureListener {
private ListView list;

public MyGestureDetector(ListView list) {
    this.list = list;
}

//CONDITIONS ARE TYPICALLY VELOCITY OR DISTANCE    
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    if (INSERT_CONDITIONS_HERE)
        if (showDeleteButton(e1))
            return true;
    return super.onFling(e1, e2, velocityX, velocityY);
}

private boolean showDeleteButton(MotionEvent e1) {
    int pos = list.pointToPosition((int)e1.getX(), (int)e1.getY());
    return showDeleteButton(pos);
}

private boolean showDeleteButton(int pos) {
    View child = list.getChildAt(pos);
    if (child != null){
        Button delete = (Button) child.findViewById(R.id.delete_button_id);
        if (delete != null)
            if (delete.getVisibility() == View.INVISIBLE)
                delete.setVisibility(View.VISIBLE);
            else
                delete.setVisibility(View.INVISIBLE);
        return true;
    }
    return false;
}
}

and call this class as following:

MyGestureDetector(YOUR_LIST);

EDIT:

To detect swipe, use following conditions:

private static final int SWIPE_MIN_DISTANCE = 80;
private static final int SWIPE_THRESHOLD_VELOCITY = 50;
private static final int PEOPLE_FRAGMENT = 0;
private static final int PLACES_FRAGMENT = 2;

And conditions for swip up, down, right and left are: (In your case only one is needed, either right or left).

  if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY){
    Log.d("SWIPE", "right to left");
    return true; //Right to left
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY){
    Log.d("SWIPE", "left to right");
    return true; //Left to right 
}

//This will test for up and down movement. 
if(e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY){
    return false; //Bottom to top
} else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY){
    return false; //Top to bottom 
}

Now add that showDeleteButton() in either right to left or left to right. And also note that you can also detect small swipe by changing the values of final variables given above.

Hope this will help you :)

like image 129
Kaushal28 Avatar answered Oct 18 '25 12:10

Kaushal28


Hope This will help you,

public class OnSwipeTouchListener implements View.OnTouchListener {


    private final String TAG = OnSwipeTouchListener.class.getSimpleName();
    ListView list;
    private GestureDetector gestureDetector;
    private Context context;


    public OnSwipeTouchListener(Context ctx, ListView list) {
        gestureDetector = new GestureDetector(ctx, new GestureListener());
        context = ctx;
        this.list = list;
    }

    public OnSwipeTouchListener() {
        super();
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }

    public void onSwipeRight(int pos) {
        //Do what you want after swiping left to right

        Log.e(TAG, "onSwipeRight: " + pos);

        mShopAdapter.swipeRight(pos);
    }

    public void onSwipeLeft(int pos) {

        //Do what you want after swiping right to left
        Log.e(TAG, "onSwipeLeft: " + pos);
        mShopAdapter.swipeLeft(pos);
    }

    private final class GestureListener extends GestureDetector.SimpleOnGestureListener {

        private static final int SWIPE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;

        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }

        private int getPostion(MotionEvent e1) {
            return list.pointToPosition((int) e1.getX(), (int) e1.getY());
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2,
                               float velocityX, float velocityY) {
            float distanceX = e2.getX() - e1.getX();
            float distanceY = e2.getY() - e1.getY();
            if (Math.abs(distanceX) > Math.abs(distanceY)
                    && Math.abs(distanceX) > SWIPE_THRESHOLD
                    && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                if (distanceX > 0)
                    onSwipeRight(getPostion(e1));
                else
                    onSwipeLeft(getPostion(e1));
                return true;
            }
            return false;
        }

    }


}

Then Attach to ListView

 mLstShopList.setOnTouchListener(new OnSwipeTouchListener(getActivity(),
                mLstShopList));

-mShopAdapter - Your adapter

you will get left and right swipe gesture inside your adapter.

like image 42
Dhara Avatar answered Oct 18 '25 14:10

Dhara



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!