一、获取悬浮窗权限。
? ? ? ? 1.在android6.0之前想要用WindowManager是不需要动态申请权限的,只需要静态写入清单文件:android.permission.SYSTEM_ALTER_WINDOW 即可。 ? ? ? ? 2.动态跳转到系统权限申请页面:
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
? ? ? ? ? ? if(!Settings.canDrawOverlays(this)){
? ? ? ? ? ? ? ? Intent permission = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
? ? ? ? ? ? ? ? permission.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
? ? ? ? ? ? ? ? startActivityForResult(permission,1);
? ? ? ? ? ? }
?}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//此处加入权限的相关判断...
}
二、设置相关Flag并添加悬浮的View。
WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
windowParams = new WindowManager.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
windowParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
windowParams.type = WindowManager.LayoutParams.TYPE_PHONE;
}
windowParams.flags = WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
windowParams.format = PixelFormat.RGBA_8888;
windowParams.x = point.x;
windowParams.y = point.y;
windowManager.addView(view, windowParams);
?三、设置View的onTouch。
//设置可以拖拽的区域(也可以设置整个屏幕区域)
Rect rect = new Rect();
rect.left = 0;
rect.right = 1280;
rect.top = 0;
rect.bottom = 720;
//如果想要沉浸式,那么需要获取状态栏的高度
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
int statusBarHeight = getResources().getDimensionPixelSize(resourceId);
因为windowParams的x和y值指的是悬浮窗中心的位置,所以View也要按照控件中心点进行计算。
int viewWidth = view.getWidth() / 2;
int viewHeight = view.getHeight() / 2;
//对WindowManeger里面的view进行设置OnTouch监听。
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
float lastX = 0;
float lastY = 0;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
lastX = event.getRawX();
lastY = event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
float rawX = event.getRawX();
float rawY = event.getRawY();
//进行横向边缘检测,以防止越界
if (rawX < rect.left + width) {
rawX = rect.left + width;
} else if (rawX > rect.right - width) {
rawX = rect.right - width;
}
//进行纵向边缘检测,以防止越界
if (rawY < rect.top + height) {
rawY = rect.top + height - statusBarHeight;
} else if (rawY > rect.bottom - height) {
rawY = rect.bottom - height;
}
windowParams.x = (int) (rawX - lastX) - width;
//如果需要沉浸式则需要减去状态栏的高度
//windowParams.y = (int) (rawY - lastY) - height - statusBarHeight;
windowParams.y = (int) (rawY - lastY) - height;
windowManager.updateViewLayout(view, windowParams);
break;
}
return false;
}
});
|