Android 全屏悬浮窗适配(悬浮窗沉浸式)

  • 前言
    由于Android 高版本的类型限制,如果我们使用WindowsManager 做悬浮窗,会被限制在当前窗口内容中。而当前窗口大小会限制在状态栏和导航栏之间,所以会导致悬浮窗沉浸不了状态栏。

高版本windowsmanager 限制 源码


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//6.0+
            mParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

        } else {
            mParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
        }

        /**
         * Window type: Application overlay windows are displayed above all activity windows
         * (types between {@link #FIRST_APPLICATION_WINDOW} and {@link #LAST_APPLICATION_WINDOW})
         * but below critical system windows like the status bar or IME.
         * <p>
         * The system may change the position, size, or visibility of these windows at anytime
         * to reduce visual clutter to the user and also manage resources.
         * <p>
         * Requires {@link android.Manifest.permission#SYSTEM_ALERT_WINDOW} permission.
         * <p>
         * The system will adjust the importance of processes with this window type to reduce the
         * chance of the low-memory-killer killing them.
         * <p>
         * In multi-user systems shows only on the owning user's screen.
         */
        public static final int TYPE_APPLICATION_OVERLAY = FIRST_SYSTEM_WINDOW + 38;


上面注解简单描述的意思就是:

应用程序覆盖窗口显示在所有活动窗口之上 ,但是级别会低于状态栏和IME,所以,从这里我们可以看出,当我们使用type=TYPE_APPLICATION_OVERLAY, 是很难将窗口沉浸到状态栏上的。

那要怎么做呢?

高版本WindowManager 沉浸状态栏

创建WindowManager 和LayoutParams

 WindowManager  wManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
 WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();

设置Params 参数

        mParams.format = PixelFormat.TRANSLUCENT;// 支持透明
        //mParams.format = PixelFormat.RGBA_8888;l
//        mParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;// 焦点

        mParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                // 加上这句话悬浮窗不拦截事件
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                | WindowManager.LayoutParams.FLAG_FULLSCREEN
                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;

注意看,这里有一句核心,WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
意思是,不受边界影响,可以超出窗口边界!!!

加载布局,设置布局沉浸~

        View  inflate = LayoutInflater.from(this).inflate(R.layout.view_widow_layout, null);

        ImageView   imageView = inflate.findViewById(R.id.iv);
        imageView.setScaleType(ImageView.ScaleType.FIT_XY);

        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) imageView.getLayoutParams();
        layoutParams.topMargin=-StatusBarUtils.getStatusBarHeight(this);
        imageView.setLayoutParams(layoutParams);

       wManager.addView(inflate, mParams);//添加窗口

核心: layoutParams.topMargin=-StatusBarUtils.getStatusBarHeight(this);
通过获取状态栏高度,设置布局的margin为负数达到超出边界刚好为状态栏的高度,从而达到沉浸式效果!!

最后附上获取状态栏高度

    /**
     * 获取状态栏高度
     * @param context
     * @return
     */
    public static int getStatusBarHeight(Context context) {
        Resources resources = context.getResources();
        int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
        int height = resources.getDimensionPixelSize(resourceId);
        return height;
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值