ListView item滑动删除

  • 仿QQListView滑动删除
  • 用PopupWindow实现ListView item的滑动删除,学习view事件传递机制
  • 代码注释很全,这里不做详细说明
  • 冰冻三尺非一日之寒,有时间就写,写写更健康

1. 自定义ListView
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
import 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引用
1
2
3
4
5
<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. 测试
1
2
3
4
5
6
7
8
9
10
11
12
listView = (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();
}
});


亦菲表演机器猫