自定义实现ListView左滑删除

来源:互联网 发布:视唱练耳软件 编辑:程序博客网 时间:2024/05/18 01:09

首先声明,此博文得益于一叶漂舟大神的点击打开链接的博客,谢谢分享。

这里只实现当有滑动速度时才会出现删除按钮,而不是像qq那样随着滑动一点一点出来的,qq那个后面再研究。

先看自定义的View的代码:

package com.hardy.person.housingestate.activities;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.GestureDetector;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.widget.ListView;import android.widget.RelativeLayout;import android.widget.TextView;import com.hardy.person.housingestate.R;/** * @author 马鹏昊 * @date {2016-10-12} * @des 自定义左滑删除ListView * @updateAuthor * @updateDate * @updateDes */public class MyListView extends ListView implements View.OnTouchListener,GestureDetector.OnGestureListener{    private String TAG = "MyListView";    //GestureDetector对象,注意要使用android.view.GestureDetector这个包下的    private GestureDetector gestureDetector ;    //自定义删除回调接口    private OnDeleteListener listener;    //删除按钮    private View deleteButton;    //触发左滑事件的Item    private ViewGroup itemLayout;    //记录触发触摸事件的点是属于adapter哪个项(由pointToPosition方法获得)    private int selectedItem;    //标志着删除按钮是否已经出现    private boolean isDeleteShown;    public MyListView(Context context) {        super(context);    }    public MyListView(Context context,AttributeSet set) {        super(context, set);        //第二个参数是OnGestureListener对象        gestureDetector = new GestureDetector(getContext(),this);        //一开始触摸事件会先被OnTouchListener捕获,onTouch()方法里去分配事件给GestureDetector,他才会有资格处理        setOnTouchListener(this);    }    @Override    public boolean onDown(MotionEvent e) {        //测试三个方法的作用        //pointToPosition(x ,y )方法是得到指定的xy点的Itemadapter中的位置        int po = pointToPosition((int) e.getX(), (int) e.getY());        Log.d(TAG, "pointToPosition()返回的值:   " + po);        //getFirstVisiblePosition()方法是得到屏幕中可见的第一个Itemadapter中的位置        int firstVisiblePosition = getFirstVisiblePosition();        Log.d(TAG, "getFirstVisiblePosition()返回的值:   " + firstVisiblePosition);        int index = po - firstVisiblePosition ;        Log.d(TAG, "pointToPosition()返回的值 - getFirstVisiblePosition()返回的值:   "+index);        //getChildAt(index)方法是得到在屏幕中可见的这些Item中的index位置的Itemindex不是在adapter中的位置,而是屏幕中可见的Item的位置        TextView textView = (TextView) getChildAt(index);        Log.d(TAG, "得到的ItemView的值:   " + textView.getText().toString());        //如果删除按钮还不可见,得到点击的是在adapter中的位置        if (!isDeleteShown) {            selectedItem = pointToPosition((int) e.getX(), (int) e.getY());        }        return false;    }    //设置删除listener    public void setOnDeleteListener(OnDeleteListener l) {        listener = l;    }    //只要是按下没有抬起时触发,而onLongPress是当按住到达一定时间才能触发    @Override    public void onShowPress(MotionEvent e) {    }    //没有滑动,单击up时触发    @Override    public boolean onSingleTapUp(MotionEvent e) {        return false;    }    //当滑动时触发,并且distanceXdistanceY是上一次触发onScroll时的xy到此次onScroll时的相应的距离,并不是到onDown时的相应距离    @Override    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {        return false;    }    //毋庸置疑,当长按时触发    @Override    public void onLongPress(MotionEvent e) {    }    //当滑动的事件up时有加速度时触发    @Override    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {        //如果删除按钮还不可见,并且x方向的加速度大于y方向的加速度则证明是横行滑动的,则显示删除按钮        if (!isDeleteShown && Math.abs(velocityX) > Math.abs(velocityY)) {            //通过inflater得到删除按钮            deleteButton = LayoutInflater.from(getContext()).inflate(                    R.layout.delete_button, null);            //添加点击事件            deleteButton.setOnClickListener(new OnClickListener() {                @Override                public void onClick(View v) {                    //从触发左滑事件的Item中移除掉删除按钮                    itemLayout.removeView(deleteButton);                    deleteButton = null;                    //标志删除按钮不可见                    isDeleteShown = false;                    //执行删除时你要做的回调方法(移除该Item                    listener.onDelete(selectedItem);                }            });            //找到触发左滑事件的Item            itemLayout = (ViewGroup) getChildAt(selectedItem                    - getFirstVisiblePosition());            //设置要添加的删除按钮的参数和对齐方式            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);            //addRule()方法设置layout动词,可以理解为设置对齐方式            params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);            params.addRule(RelativeLayout.CENTER_VERTICAL);//            //设置要添加的删除按钮的参数和对齐方式//            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(//                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);            //给该Item添加删除按钮            itemLayout.addView(deleteButton, params);            //标志删除按钮可见            isDeleteShown = true;        }        return false;    }    @Override    public boolean onTouch(View v, MotionEvent event) {        //如果删除按钮现在正可见,那么本次点击后,删除按钮隐藏        if (isDeleteShown) {            itemLayout.removeView(deleteButton);            deleteButton = null;            //标志删除按钮不可见            isDeleteShown = false;            return false;        } else {            //否则把触摸事件交给GestureDetector去处理左滑事件            return gestureDetector.onTouchEvent(event);        }    }    //删除回调接口    public interface OnDeleteListener {        void onDelete(int index);    }}

仔细看注释就能明白。

特意说一下:

触摸事件首先会被onTouchListener捕获,所以GestureDetector要想处理触摸事件必须在onTouch()方法里被分配了事件才行,所以整个事件的入口在onTouch()。

//否则把触摸事件交给GestureDetector去处理左滑事件return gestureDetector.onTouchEvent(event);
Activity里设置删除监听方法和adapter即可:

final List<String> contentList = new ArrayList<>();contentList.add("Content Item 1");contentList.add("Content Item 2");contentList.add("Content Item 3");contentList.add("Content Item 4");contentList.add("Content Item 5");contentList.add("Content Item 6");contentList.add("Content Item 7");contentList.add("Content Item 8");contentList.add("Content Item 9");contentList.add("Content Item 10");contentList.add("Content Item 11");contentList.add("Content Item 12");contentList.add("Content Item 13");contentList.add("Content Item 14");contentList.add("Content Item 15");contentList.add("Content Item 16");contentList.add("Content Item 17");contentList.add("Content Item 18");contentList.add("Content Item 19");contentList.add("Content Item 20");final ArrayAdapter arrayAdapter = new ArrayAdapter(this,R.layout.asdasdasd,R.id.text,contentList);MyListView myListView = (MyListView) findViewById(R.id.asd);myListView.setOnDeleteListener(new MyListView.OnDeleteListener() {    @Override    public void onDelete(int index) {        contentList.remove(index);        arrayAdapter.notifyDataSetChanged();    }});myListView.setAdapter(arrayAdapter);
ok!完工!!







1 0
原创粉丝点击