-
Notifications
You must be signed in to change notification settings - Fork 1
/
ZMoveFloatButton.java
121 lines (109 loc) · 4.56 KB
/
ZMoveFloatButton.java
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
package com.milkz.ui.button;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.support.design.widget.FloatingActionButton;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
/**
* Create by zuoqi@bhz.com.cn on 2019/11/6 17:20
* <p>
* 可移动的悬浮按钮,但是这种悬浮按钮,无法设置按钮背景色为自定义background
* </p>
*/
public class ZMoveFloatButton extends FloatingActionButton {
private static final String TAG = "MoveFloatButton";
private boolean isDrag;
private boolean ifMove;
private int lastX;
private int lastY;
private int screenWidth;
private int screenHeight;
private int screenWidthHalf;
private int statusHeight;
private int virtualHeight;
public ZMoveFloatButton(Context context) {
this(context, null);
}
public ZMoveFloatButton(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ZMoveFloatButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
screenWidth = ScreenUtils.getScreenWidth(getContext());
screenWidthHalf = screenWidth / 2;
screenHeight = ScreenUtils.getScreenHeight(getContext());
statusHeight = ScreenUtils.getStatusHeight(getContext());
virtualHeight = ScreenUtils.getVirtualBarHeigh(getContext());
}
// TODO 移动偶尔会触发点击事件
@Override
public boolean onTouchEvent(MotionEvent ev) {
int rawX = (int) ev.getRawX();
int rawY = (int) ev.getRawY();
switch (ev.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
isDrag = false;
ifMove = false;
getParent().requestDisallowInterceptTouchEvent(true); // 在down的时候,屏蔽父类的事件屏蔽
lastX = rawX;
lastY = rawY;
break;
case MotionEvent.ACTION_MOVE:
isDrag = true;
//计算手指移动了多少
int dx = rawX - lastX;
int dy = rawY - lastY;
//这里修复一些手机无法触发点击事件的问题
int distance = (int) Math.sqrt(dx * dx + dy * dy);// 勾股计算移动距离
Log.e("distance---->", distance + "");
if (distance < 3) {//给个容错范围,不然有部分手机还是无法点击
isDrag = false;
break;
}
ifMove = true;
float x = getX() + dx;
float y = getY() + dy;
//检测是否到达边缘 左上右下
x = x < 0 ? 0 : x > screenWidth - getWidth() ? screenWidth - getWidth() : x;
// y = y < statusHeight ? statusHeight : (y + getHeight() >= screenHeight ? screenHeight - getHeight() : y);
if (y < 0) {
y = 0;
}
if (y > screenHeight - statusHeight - getHeight()) {
y = screenHeight - statusHeight - getHeight();
}
setX(x);
setY(y);
lastX = rawX;
lastY = rawY;
Log.e("move---->", "getX=" + getX() + ";screenWidthHalf=" + screenWidthHalf + " "
+ isDrag + " statusHeight=" + statusHeight + " virtualHeight" + virtualHeight
+ " screenHeight" + screenHeight + " getHeight=" + getHeight() + " y" + y);
break;
case MotionEvent.ACTION_UP:
Log.d(TAG, "ACTION_UP !");
if (isDrag)
//恢复按压效果
setPressed(false);
if (rawX >= screenWidthHalf) {
animate().setInterpolator(new DecelerateInterpolator())
.setDuration(500)
.xBy(screenWidth - getWidth() - getX())
.start();
} else {
ObjectAnimator oa = ObjectAnimator.ofFloat(this, "x", getX(), 0);
oa.setInterpolator(new DecelerateInterpolator());
oa.setDuration(500);
oa.start();
}
break;
}
//如果是拖拽则消耗事件,否则正常传递即可。
return (ifMove || isDrag || super.onTouchEvent(ev));
}
}