ListView item滑动删除 发表于 2016-10-25 | 分类于 自定义view | 仿QQListView滑动删除 用PopupWindow实现ListView item的滑动删除,学习view事件传递机制 代码注释很全,这里不做详细说明 冰冻三尺非一日之寒,有时间就写,写写更健康 1. 自定义ListView123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.Gravity;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;import android.widget.Button;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.PopupWindow;/** * Created by zhangfeng on 2016/10/24. */public class DeleteListView extends ListView { private static final String TAG = "DeleteListView"; /** * 滑动的最小距离 */ private int touchSolp; /** * 是否滑动 */ private boolean isSliding; /** * 手指按下X坐标 */ private int xDown; /** * 手指按下Y坐标 */ private int yDown; /** * 手指移动X坐标 */ private int xMove; /** * 手指移动Y坐标 */ private int yMove; /** * 当前手指触摸的view */ private View mCurrentView; /** * 当前手指触摸的位置 */ private int mCurrentViewPos; private LayoutInflater inflater; private PopupWindow popupWindow; private int popWindowHeight; private int popWindowWidht; private Button deleteBtn; /** * 为删除按钮提供一个回掉接口 */ private DelButtonClickListener mListener; /** * 初始化 * @param context * @param attrs */ public DeleteListView(Context context, AttributeSet attrs) { super(context, attrs); inflater = LayoutInflater.from(context); touchSolp = ViewConfiguration.get(context).getScaledTouchSlop(); View view = inflater.inflate(R.layout.view_list_item, null); deleteBtn = (Button) view.findViewById(R.id.delete); popupWindow = new PopupWindow(view, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); //先调用下measure 否则拿不到宽高 popupWindow.getContentView().measure(0, 0); popWindowHeight = popupWindow.getContentView().getMeasuredHeight(); popWindowWidht = popupWindow.getContentView().getMeasuredWidth(); } @Override public boolean dispatchTouchEvent(MotionEvent event) { int action = event.getAction(); int x = (int) event.getX(); int y = (int) event.getY(); switch (action) { case MotionEvent.ACTION_DOWN: xDown = x; yDown = y; /** * 如果当前popwindow 显示 则直接隐藏,屏蔽 touch事件的向下传递 */ if (popupWindow.isShowing()) { dismissPopwindow(); return false; } //获得当前手指按下 item的位置 mCurrentViewPos = pointToPosition(xDown, yDown); //获得当前手指按下的 view View view = getChildAt(mCurrentViewPos - getFirstVisiblePosition()); mCurrentView = view; break; case MotionEvent.ACTION_MOVE: xMove = x; yMove = y; int dx = xMove - xDown; int dy = yMove - yDown; /** * 判断是否从右到左滑动 */ if (xMove < xDown && Math.abs(dx) > touchSolp && Math.abs(dy) < touchSolp) { Log.e(TAG, "touchslop = " + touchSolp + " , dx = " + dx + " , dy = " + dy); isSliding = true; } break; } return super.dispatchTouchEvent(event); } private void dismissPopwindow() { if (popupWindow != null && popupWindow.isShowing()) { popupWindow.dismiss(); } } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); /** * 如果从右到左才响应 movie事件 */ if (isSliding) { switch (action) { case MotionEvent.ACTION_MOVE: int[] location = new int[2]; //获得当前 item 的X与Y mCurrentView.getLocationOnScreen(location); popupWindow.setAnimationStyle(R.style.popwindow_delete_btn_anim_style); popupWindow.update(); popupWindow.showAtLocation(mCurrentView, Gravity.LEFT | Gravity.TOP, location[0] + mCurrentView.getWidth(), location[1] + mCurrentView.getHeight() / 2 - popWindowHeight / 2); deleteBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (mListener != null) { mListener.clickHappend(mCurrentViewPos); popupWindow.dismiss(); } } }); break; case MotionEvent.ACTION_UP: isSliding = false; } return true; } return super.onTouchEvent(event); } public void setDelButtonClickListener(DelButtonClickListener listener) { mListener = listener; } interface DelButtonClickListener { public void clickHappend(int posiotion); }} 2. xml引用12345<com.cn.test.DeleteListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" android:listSelector="#00000000"></com.cn.test.DeleteListView> 2. 测试123456789101112listView = (DeleteListView) findViewById(R.id.listView); mDatas = new ArrayList<>(Arrays.asList("Java", "Android", "Python", "Ruby", "Servlet", "Struts", "Hibernate", "Spring", "HTML5", "Javascript", "Jquery")); adapter = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1, mDatas); listView.setAdapter(adapter); listView.setDelButtonClickListener(new DeleteListView.DelButtonClickListener() { @Override public void clickHappend(int posiotion) { adapter.remove(adapter.getItem(posiotion)); adapter.notifyDataSetChanged(); } });