版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mr_jianrong/article/details/78989981
这是控件的主代码,在你的项目里面,新建一个同名的类,把代码直接复制进去就能用了。另外,这个类里面引用了工具类的一些代码。工具类在这个主类的源码下面也有贴出,直接把工具类的相关代码,复制到你自己的工具类里就行了,有问题可以加我QQ咨询:326257241。
/**
* @ClassName: FloatDragView
* @Description: 可拖动的悬浮按钮
* @Author: 阿荣
* @Date:2016/3/18
*/
public class FloatDragView {
private Activity context; // 上下文
private ImageView mImageView; // 可拖动按钮
private static int mScreenWidth = -1; //屏幕的宽度
private static int mScreenHeight = -1; //屏幕的高度
private int relativeMoveX; // 控件相对屏幕左上角移动的位置X
private int relativeMoveY; // 控件相对屏幕左上角移动的位置Y
private boolean isIntercept = false; // 是否截断touch事件
private int startDownX; // 按下时的位置控件相对屏幕左上角的位置X
private int startDownY; // 按下时的位置控件距离屏幕左上角的位置Y
private static int[] lastPosition; // 用于记录上一次的位置(坐标0对应x,坐标1对应y)
/**
* @param context 上下文
* @param mViewContainer 可拖动按钮要存放的对应的Layout
* @param clickListener 可拖动按钮的点击事件
*/
public static ImageView addFloatDragView(Activity context , RelativeLayout mViewContainer,
View.OnClickListener clickListener) {
FloatDragView floatDragView = new FloatDragView(context);
ImageView imageView = floatDragView.getFloatDragView(clickListener);
mViewContainer.addView(imageView);
return imageView;
}
// 初始化实例
private FloatDragView(Activity context) {
setScreenHW(context);
this.context = context;
lastPosition = new int[]{0,0};
}
// 获取可拖动按钮的实例
private ImageView getFloatDragView(View.OnClickListener clickListener) {
if (mImageView != null) {
return mImageView;
} else {
mImageView = new ImageView(context);
mImageView.setClickable(true);
mImageView.setFocusable(true);
mImageView.setImageResource(R.drawable.analyze_btn_selector);
setFloatDragViewParams(mImageView);
mImageView.setOnClickListener(clickListener);
setFloatDragViewTouch(mImageView);
return mImageView;
}
}
// 设置可拖动按钮的位置参数
private void setFloatDragViewParams(View floatDragView) {
// 记录最后图片在窗体的位置
int moveX = lastPosition[0];
int moveY = lastPosition[1];
if (0 != moveX || 0 != moveY) {// 移动后的位置
// 每次移动都要设置其layout,不然由于父布局可能嵌套listView,当父布局发生改变冲毁(如下拉刷新时)则移动的view会回到原来的位置
RelativeLayout.LayoutParams lpFeedback = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lpFeedback.setMargins(moveX, moveY, 0, 0);
floatDragView.setLayoutParams(lpFeedback);
} else {// 初始位置
RelativeLayout.LayoutParams lpFeedback = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lpFeedback.setMargins(0, 0, 20, 218);
lpFeedback.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
lpFeedback.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
floatDragView.setLayoutParams(lpFeedback);
}
}
// 可拖动按钮的touch事件
private void setFloatDragViewTouch(final ImageView floatDragView) {
floatDragView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(final View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
isIntercept = false;
startDownX = relativeMoveX = (int) event.getRawX();
startDownY = relativeMoveY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
int dx = (int) event.getRawX() - relativeMoveX;
int dy = (int) event.getRawY() - relativeMoveY;
int left = v.getLeft() + dx;
int top = v.getTop() + dy;
int right = v.getRight() + dx;
int bottom = v.getBottom() + dy;
if (left < 0) {
left = 0;
right = left + v.getWidth();
}
if (right > mScreenWidth) {
right = mScreenWidth;
left = right - v.getWidth();
}
if (top < 0) {
top = 0;
bottom = top + v.getHeight();
}
if (bottom > mScreenHeight) {
bottom = mScreenHeight;
top = bottom - v.getHeight();
}
v.layout(left, top, right, bottom);
relativeMoveX = (int) event.getRawX();
relativeMoveY = (int) event.getRawY();
break;
case MotionEvent.ACTION_UP:
int lastMoveDx = Math.abs((int) event.getRawX() - startDownX);
int lastMoveDy = Math.abs((int) event.getRawY() - startDownY);
if (5 < lastMoveDx || 5 < lastMoveDy) {// 防止点击的时候稍微有点移动点击事件被拦截了
isIntercept = true;
} else {
isIntercept = false;
}
// 每次移动都要设置其layout,不然由于父布局可能嵌套listview,
// 当父布局发生改变冲毁(如下拉刷新时)则移动的view会回到原来的位置
RelativeLayout.LayoutParams lpFeedback = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lpFeedback.setMargins(v.getLeft(), v.getTop(), 0, 0);
v.setLayoutParams(lpFeedback);
// preferenceUtil.saveInt("moveX", v.getLeft());
// preferenceUtil.saveInt("moveY", v.getTop());
// 设置靠近边沿的
setImageViewNearEdge(v);
break;
}
return isIntercept;
}
});
}
// 将拖动按钮移动到边沿
private void setImageViewNearEdge(final View v) {
if (v.getLeft() < ((Utils.getScreenSize(context).x) / 2)) {
// 设置位移动画 向左移动控件位置
final TranslateAnimation animation = new TranslateAnimation(0, -v.getLeft(), 0, 0);
animation.setDuration(300);// 设置动画持续时间
animation.setRepeatCount(0);// 设置重复次数
animation.setFillAfter(true);
animation.setRepeatMode(Animation.ABSOLUTE);
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation arg0) {
// TODO: 2017/3/1
}
@Override
public void onAnimationRepeat(Animation arg0) {
// TODO: 2017/3/1
}
@Override
public void onAnimationEnd(Animation arg0) {
v.clearAnimation();
RelativeLayout.LayoutParams lpFeedback = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lpFeedback.setMargins(0, v.getTop(), 0, 0);
v.setLayoutParams(lpFeedback);
v.postInvalidateOnAnimation();
lastPosition[0] = 0;
lastPosition[1] = v.getTop();
}
});
v.startAnimation(animation);
} else {
final TranslateAnimation animation = new TranslateAnimation(0, (Utils.getScreenSize(context).x
- v.getLeft() - v.getWidth()), 0, 0);
animation.setDuration(300);// 设置动画持续时间
animation.setRepeatCount(0);// 设置重复次数
animation.setRepeatMode(Animation.ABSOLUTE);
animation.setFillAfter(true);
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation arg0) {
// TODO: 2017/3/1
}
@Override
public void onAnimationRepeat(Animation arg0) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation arg0) {
v.clearAnimation();
RelativeLayout.LayoutParams lpFeedback = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lpFeedback.setMargins(Utils.getScreenSize(context).x - v.getWidth(), v.getTop(), 0, 0);
v.setLayoutParams(lpFeedback);
v.postInvalidateOnAnimation();
lastPosition[0] =Utils.getScreenSize(context).x - v.getWidth();
lastPosition[1] = v.getTop();
}
});
v.startAnimation(animation);
}
}
// 计算屏幕的实际高宽
private void setScreenHW(Activity context) {
if (mScreenHeight < 0) {
// 减去状态栏高度,否则挨着底部移动,导致图标变小
Point screen = Utils.getScreenSize(context);
mScreenWidth = screen.x;
mScreenHeight = screen.y - Utils.getStatusBarHeight(context);
}
}
}
- 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
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
以下是工具类的代码
public class Utils {
// 状态栏高度
private static int statusBarHeight = 0;
// 屏幕像素点
private static final Point screenSize = new Point();
// 获取屏幕像素点
public static Point getScreenSize(Activity context) {
if (context == null) {
return screenSize;
}
WindowManager wm = (WindowManager) context
.getSystemService(Context.WINDOW_SERVICE);
if (wm != null) {
DisplayMetrics mDisplayMetrics = new DisplayMetrics();
Display diplay = wm.getDefaultDisplay();
if (diplay != null) {
diplay.getMetrics(mDisplayMetrics);
int W = mDisplayMetrics.widthPixels;
int H = mDisplayMetrics.heightPixels;
if (W * H > 0 && (W > screenSize.x || H > screenSize.y)) {
screenSize.set(W, H);
}
}
}
return screenSize;
}
// 获取状态栏高度
public static int getStatusBarHeight(Context context) {
if (statusBarHeight <= 0) {
Rect frame = new Rect();
((Activity) context).getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
statusBarHeight = frame.top;
}
if (statusBarHeight <= 0) {
try {
Class<?> c = Class.forName("com.android.internal.R$dimen");
Object obj = c.newInstance();
Field field = c.getField("status_bar_height");
int x = Integer.parseInt(field.get(obj).toString());
statusBarHeight = context.getResources().getDimensionPixelSize(x);
} catch (Exception e1) {
e1.printStackTrace();
}
}
return statusBarHeight;
}
}
- 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
使用方法
mRootView 就是要出现悬浮按钮的界面的根view。就是setContentView的View。
FloatDragView.addFloatDragView(this, mRootView, new View.OnClickListener() {
@Override
public void onClick(View view) {
// 点击事件
}
});