超级简单代码实现滑动退出
本文参考自 http://www.jianshu.com/p/59be4551c418
OK,接下来惯例,通过阅读本文你能学习到:
ViewDragHelper的使用(如果你想学习自定义View,那么ViewDragHelper你绝对不能错过)
好像也没有什么了….
这个效果,难度不大,会ViewDragHelper的同学应该10分钟就能写出来了吧~
如果不会也没关系~以下是代码,请查看。
自定义Layout : SwipeBackFrameLayout
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
125public class SwipeBackFrameLayout extends FrameLayout {
private ViewDragHelper mDragHelper;
private int mDividerWidth = 100;
private int mLastdx;
public SwipeBackFrameLayout(Context context) {
super(context);
initView();
}
public SwipeBackFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public SwipeBackFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
mDividerWidth = mDividerView.getWidth();
}
//Notice view 刚初始化的时候就会被调用一次
public void computeScroll() {
super.computeScroll();
if (mDragHelper.continueSettling(true)) {
invalidate();
}
}
private void initView() {
// 1f代表灵敏度
mDragHelper = ViewDragHelper.create(this, 1f, new ViewDragHelper.Callback() {
public void onViewDragStateChanged(int state) {
super.onViewDragStateChanged(state);
//滑动停止,并且到达了滑动的判断条件 则回调关闭
if (mDragHelper.getViewDragState() == ViewDragHelper.STATE_IDLE && mcCallBack != null && mDividerWidth == mContentView.getLeft() && mLastdx > 0) {
mcCallBack.onShouldFinish();
}
}
public void onEdgeTouched(int edgeFlags, int pointerId) {
super.onEdgeTouched(edgeFlags, pointerId);
// 触摸到边界的时候, 我们capture注mContentView
mDragHelper.captureChildView(mContentView, pointerId);
}
public int getViewHorizontalDragRange(View child) {
return 1;
}
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
super.onViewPositionChanged(changedView, left, top, dx, dy);
Log.d("ZTJ", "onViewPositionChanged() called with left = [" + left + "], top = [" + top + "], dx = [" + dx + "], dy = [" + dy + "]");
//0.0 - 1.0
//Notice 这边可以给个接口回调出去,就可以做各种炫酷的效果了
float alpha = (float) (left * 1.0 / mDividerWidth);
mDividerView.setAlpha(alpha);
}
public int clampViewPositionHorizontal(View child, int left, int dx) {
// 计算left 我们的目标范围是0-dividerwidth的宽度
mLastdx = dx;
int newLeft = Math.min(mDividerWidth, Math.max(left, 0));
return newLeft;
}
public void onViewReleased(View releasedChild, float xvel, float yvel) {
//>0代表用户想关闭
if (mLastdx > 0) {
// 还不到关闭条件,我们让view滑动过去,再关闭
if (mDividerWidth != releasedChild.getLeft()) {
mDragHelper.settleCapturedViewAt(mDividerWidth, releasedChild.getTop());
invalidate();
} else {
if (mcCallBack != null) {
mcCallBack.onShouldFinish();
}
}
} else {
//用户不想关闭 ,则滑动到最左边
if (mDividerWidth != 0) {
mDragHelper.settleCapturedViewAt(0, releasedChild.getTop());
invalidate();
}
}
}
public boolean tryCaptureView(View child, int pointerId) {
return false;
}
});
// 滑动范围
mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
}
// 右侧要出现的View
private View mDividerView;
// 内容
private View mContentView;
protected void onFinishInflate() {
super.onFinishInflate();
mDividerView = getChildAt(0);
mDividerView.setAlpha(0f);
mContentView = getChildAt(1);
}
// 设置finish 回调
public void setCallBack(CallBack mCallBack) {
this.mcCallBack = mCallBack;
}
private CallBack mcCallBack;
public interface CallBack {
void onShouldFinish();
}
// 让ViewDragHelper来处理Touch事件
public boolean onInterceptTouchEvent(MotionEvent ev) {
return mDragHelper.shouldInterceptTouchEvent(ev);
}
public boolean onTouchEvent(MotionEvent event) {
mDragHelper.processTouchEvent(event);
return true;
}
}layout.xml : activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<io.github.jungletian.gradle_export_jar.SwipeBackFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swipe_back"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="40dp"
android:layout_height="match_parent"
android:background="#ffff00"
android:gravity="center"
android:text="@string/hello_world" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff00ff" />
</io.github.jungletian.grad
le_export_jar.SwipeBackFrameLayout>动画 : no_anim.xml 与 out_to_right.xml
1
2
3
4
5<alpha
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:fromAlpha="1.0"
android:toAlpha="1.0"></alpha>
,1
2
3
4<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:fromXDelta="0%"
android:toXDelta="100%"></translate>
- Activity :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class MainActivity extends AppCompatActivity {
SwipeBackFrameLayout mSwipeBack;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSwipeBack = (SwipeBackFrameLayout) findViewById(R.id.swipe_back);
mSwipeBack.setCallBack(new SwipeBackFrameLayout.CallBack() {
public void onShouldFinish() {
finish();
overridePendingTransition(R.anim.no_anim, R.anim.out_to_right);
}
});
}
}