通过WindowManager添加可移动的全局悬浮窗

一、获取悬浮窗权限。

        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;
	}
   });

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值