//悬浮按钮 自定义view
public class DragFloatActionButton extends android.support.v7.widget.AppCompatImageView {
private int parentHeight;
private int parentWidth;
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
setAlpha(0.3f);
}
};
private int lastX;
private int lastY;
private boolean isDrag;
private ViewGroup parent;
public DragFloatActionButton(Context context) {
super(context);
}
public DragFloatActionButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DragFloatActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int rawX = (int) event.getRawX();
int rawY = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
this.setAlpha(0.9f);
setPressed(true);
isDrag = false;
getParent().requestDisallowInterceptTouchEvent(true);
lastX = rawX;
lastY = rawY;
if (getParent() != null) {
parent = (ViewGroup) getParent();
parentHeight = parent.getHeight();
parentWidth = parent.getWidth();
}
break;
case MotionEvent.ACTION_MOVE:
if (parentHeight <= 0.2 || parentWidth <= 0.2) {
isDrag = false;
break;
} else {
isDrag = true;
}
this.setAlpha(0.9f);
int dx = rawX - lastX;
int dy = rawY - lastY;
//这里修复一些华为手机无法触发点击事件
int distance = (int) Math.sqrt(dx * dx + dy * dy);
if (distance == 0) {
isDrag = false;
break;
}
float x = getX() + dx;
float y = getY() + dy;
//检测是否到达边缘 左上右下
x = x < 0 ? 0 : x > parentWidth - getWidth() ? parentWidth - getWidth() : x;
y = getY() < 0 ? 0 : getY() + getHeight() > parentHeight ? parentHeight - getHeight() : y;
setX(x);
setY(y);
lastX = rawX;
lastY = rawY;
Log.i("aa", "isDrag=" + isDrag + "getX=" + getX() + ";getY=" + getY() + ";parentWidth=" + parentWidth);
break;
case MotionEvent.ACTION_UP:
if (!isNotDrag()) {
//恢复按压效果
setPressed(false);
//Log.i("getX="+getX()+";screenWidthHalf="+screenWidthHalf);
//moveHide(rawX);
} else {
myRunable();
}
break;
}
//如果是拖拽则消s耗事件,否则正常传递即可。
return !isNotDrag() || super.onTouchEvent(event);
}
private boolean isNotDrag() {
return !isDrag && (getX() == 0
|| (getX() == parentWidth - getWidth()));
}
private void moveHide(int rawX) {
if (rawX >= parentWidth / 2) {
//靠右吸附
animate().setInterpolator(new DecelerateInterpolator())
.setDuration(500)
.xBy(parentWidth - getWidth() - getX())
.start();
myRunable();
} else {
//靠左吸附
ObjectAnimator oa = ObjectAnimator.ofFloat(this, "x", getX(), 0);
oa.setInterpolator(new DecelerateInterpolator());
oa.setDuration(500);
oa.start();
myRunable();
}
}
private void myRunable() {
handler.removeCallbacks(runnable);
handler.postDelayed(runnable, 2000);
}
}
//xml布局文件
<com.martian.qplay.widget.DragFloatActionButton
android:id="@+id/circle_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_marginRight="20dp"
android:layout_marginBottom="20dp"
android:clickable="true"//是否可以拖动的属性
android:src="@mipmap/ic_launcher" />
//这些是实现悬浮框,动态开启权限
WindowManager windowManager = (WindowManager) getActivity().getApplication().getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
LayoutInflater inflater = LayoutInflater.from(getActivity().getApplication());
LinearLayout linearLayout = (LinearLayout) inflater.inflate(R.layout.drag_button, null);
if (Build.VERSION.SDK_INT >= 23) {
if (!Settings.canDrawOverlays(getActivity())) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getActivity().getPackageName()));
startActivityForResult(intent, 4444);
}
if (Build.VERSION.SDK_INT > 25) {
params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
}
}
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.MATCH_PARENT;
params.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT;
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
params.alpha = 1f;
params.format = 1;
windowManager.addView(linearLayout, params);//添加控件
windowManager.removeViewImmediate(linearLayout);//删除控件