控制View的OnClick OnTouch来实现LsitView的Item的侧滑出现删除

效果:
这里写图片描述

触摸:按下,移动,抬起
点击:一组触摸事件的组合(按下,松开)
长按:一组触摸事件的组合(按下,持续超过500ms(Android中))

为一个View设置点击事件:

1
2
3
4
5
6
view.setOnClickListener(new OnClickListener() {    
@Override
public void onClick(View v) {
Log.i("", "onClick");
}
});

为一个View设置touch事件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
view.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:
Log.i("", "ACTION_DOWN");
break;

case MotionEvent.ACTION_MOVE:
Log.i("", "ACTION_MOVE");
break;

case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
Log.i("", "ACTION_UP");
break;
}
return false;
}
});

当同时为一个View设置点击和touch事件时:

在onTouch返回false时:
这里写图片描述
当onTouch返回true时:
这里写图片描述
不在响应点击事件了

我们的需求是,在item关闭时可以响应点击事件(onTouch中返回false),在item打开时不响应点击事件(onTouch中返回true)

下面处理Touch事件:

ACTION_DOWN: 记录下手指按下的位置
ACTION_MOVE: 判断移动的距离(带正负号)移动item
ACTION_UP:根据手指抬起位置,将视图移动到合适的位置

listView 的 item 的布局

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
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="86dp"
android:layout_below="@+id/Listview" >

<TextView
android:id="@+id/more"
android:layout_width="60dp"
android:layout_height="match_parent"
android:layout_toLeftOf="@+id/delete"
android:background="@android:color/darker_gray"
android:clickable="true"
android:gravity="center"
android:onClick="more"
android:text="更多"
android:textColor="@android:color/white"
android:textSize="16sp" />

<TextView
android:id="@+id/delete"
android:layout_width="60dp"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:background="@android:color/holo_red_light"
android:clickable="true"
android:gravity="center"
android:onClick="delete"
android:text="删除"
android:textColor="@android:color/white"
android:textSize="16sp" />

<TextView
android:id="@+id/tv_top"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_orange_dark"
android:gravity="center"
android:text="item"
android:textSize="20sp" />

</RelativeLayout>

自定义的View

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
package com.zyh.slideview;

import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MoveLayout extends RelativeLayout implements OnClickListener {

private Context context;
private int downX;
private TextView tv_top;
private TextView delete;
private TextView more;

public MoveLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}

public MoveLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public MoveLayout(Context context) {
this(context, null);
}

private void init(Context context) {
this.context = context;
LayoutInflater.from(context).inflate(R.layout.move_layout, this, true);
delete = (TextView) findViewById(R.id.delete);
more = (TextView) findViewById(R.id.more);
tv_top = (TextView) findViewById(R.id.tv_top);
tv_top.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return handlerTouch(v, event);
}
});
tv_top.setOnClickListener(this);
more.setOnClickListener(this);
delete.setOnClickListener(this);
}

/* ---------------------处理 Touch-------------------------- */
boolean result = false;
boolean isOpen = false;

protected boolean handlerTouch(View v, MotionEvent event) {

int bottomWidth = delete.getWidth() + delete.getWidth();

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Log.i("", "ACTION_DOWN");
downX = (int) event.getRawX();
break;
case MotionEvent.ACTION_MOVE:
// Log.i("", "ACTION_MOVE");
// if (isAniming)
// break;
int dx = (int) (event.getRawX() - downX);
// Log.i("", "dy___" + dx);
if (isOpen) {
// 打开状态
// 向右滑动
if (dx > 0 && dx < bottomWidth) {
v.setTranslationX(dx - bottomWidth);
// 允许移动,阻止点击
result = true;
}
} else {
// 闭合状态
// 向左移动
if (dx < 0 && Math.abs(dx) < bottomWidth) {
v.setTranslationX(dx);
// 允许移动,阻止点击
result = true;
}
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:

// Log.i("", "ACTION_UP" + v.getTranslationX());

// 获取已经移动的
float ddx = v.getTranslationX();

// 判断打开还是关闭

if (ddx <= 0 && ddx > -(bottomWidth / 2)) {
// 关闭
ObjectAnimator oa1 = ObjectAnimator.ofFloat(v, "translationX", ddx, 0).setDuration(100);
oa1.start();
oa1.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}

@Override
public void onAnimationRepeat(Animator animation) {
}

@Override
public void onAnimationEnd(Animator animation) {
isOpen = false;
result = false;
}

@Override
public void onAnimationCancel(Animator animation) {
isOpen = false;
result = false;
}
});

}
if (ddx <= -(bottomWidth / 2) && ddx > -bottomWidth) {
// 打开
ObjectAnimator oa1 = ObjectAnimator.ofFloat(v, "translationX", ddx, -bottomWidth)
.setDuration(100);
oa1.start();
result = true;
isOpen = true;
}
break;
}
return result;
}

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tv_top:
Toast.makeText(context, "item", 0).show();
break;
case R.id.more:
Toast.makeText(context, "more", 0).show();
break;
case R.id.delete:
Toast.makeText(context, "delete", 0).show();
break;
}
}
}

源代码:github](https://github.com/18236887539/SlideLayout)