安卓悬浮可跳动自动吸附可设置不同的吸附距离view
DraggableImageView.java
/**
*
* @author 悬浮拖到可设置间距view
* @author 主要用于 客服组件
*/
public class DraggableImageView extends ImageView {
private float dX;// X轴偏移量
private float dY;// Y轴偏移量
private int screenWidth;// 屏幕宽度
private int screenHeight;// 屏幕高度
private int topMargin;// 上边距
private int bottomMargin;// 下边距
private int leftMargin;// 左边距
private int rightMargin;// 右边距
public DraggableImageView(Context context) {
super(context);
init(context);
}
public DraggableImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public DraggableImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
/**
* 初始化
* @param context
*/
private void init(Context context) {
int marginDp = 16;
topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginDp, context.getResources().getDisplayMetrics());
bottomMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginDp, context.getResources().getDisplayMetrics());
leftMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginDp, context.getResources().getDisplayMetrics());
rightMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginDp, context.getResources().getDisplayMetrics());
}
public void setTopMargin(int marginDp) {
topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginDp, getContext().getResources().getDisplayMetrics());
}
public void setBottomMargin(int marginDp) {
bottomMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginDp, getContext().getResources().getDisplayMetrics());
}
public void setLeftMargin(int marginDp) {
leftMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginDp, getContext().getResources().getDisplayMetrics());
}
public void setRightMargin(int marginDp) {
rightMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, marginDp, getContext().getResources().getDisplayMetrics());
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
screenWidth = ((View) getParent()).getWidth();
screenHeight = ((View) getParent()).getHeight();
}
// 处理触摸事件
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
dX = getX() - event.getRawX();
dY = getY() - event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
float newX = event.getRawX() + dX;
float newY = event.getRawY() + dY;
newX = Math.max(leftMargin, Math.min(newX, screenWidth - getWidth() - rightMargin));
newY = Math.max(topMargin, Math.min(newY, screenHeight - getHeight() - bottomMargin));
setX(newX);
setY(newY);
break;
case MotionEvent.ACTION_UP:
float centerX = getX() + getWidth() / 2;
float centerY = getY() + getHeight() / 2;
// 计算到各个水平边缘的距离
float leftDistance = centerX - leftMargin;
float rightDistance = screenWidth - getWidth() - rightMargin - centerX;
// 找到最近的水平边缘
if (leftDistance <= rightDistance) {
animate().x(leftMargin).y(centerY - getHeight() / 2).start();
} else {
animate().x(screenWidth - getWidth() - rightMargin).y(centerY - getHeight() / 2).start();
}
break;
default:
return false;
}
return true;
}
}
设置吸附边距如下
xml布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.yourpackage.DraggableImageView
android:id="@+id/draggableImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/your_image"
android:layout_centerInParent="true"/>
</RelativeLayout>
效果图如下: