DecorView与windowTranslucentStatus冲突解决

style配置了windowTranslucentStatus

true

会导致 顶部的状态栏和底部的虚拟按键区域浮起来,类似于FramLayout,DecorView在底层。这个时候在DecorView add的view就会被遮盖。

期待的效果如下


DecorView与windowTranslucentStatus冲突解决_第1张图片
期待的效果

代码如下

        decorView = (ViewGroup) activity.getWindow().getDecorView();
        displayMetrics = activity.getResources().getDisplayMetrics();
        viewParent = new LinearLayout(activity);
        viewParent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
        loadingLayout =  LayoutInflater.from(activity).inflate(R.layout.layout_loading_and_error, null,false);
        int pointY = 0;
            if (anchorView != null) {
                int[] anchorLocation = new int[2];
                anchorView.getLocationInWindow(anchorLocation);
                pointY = anchorLocation[1] + anchorView.getHeight();
            }

            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(displayMetrics.widthPixels,displayMetrics.heightPixels - pointY);
            layoutParams.width = displayMetrics.widthPixels;
            layoutParams.height = displayMetrics.heightPixels - pointY;
            layoutParams.gravity = Gravity.BOTTOM;

            viewParent.removeView(loadingLayout);//先移除再添加,防止隐藏后,再次显示,导致loadingLayout重复添加
            //添加视图
            viewParent.addView(loadingLayout, layoutParams);
            decorView.addView(viewParent);

其中anchorView是锚点的view,与PopWind中的类型,要显示在anchorView 下面。这里的anchorView 是ActionBar.
现在decorView中添加一个完全填充的LinearLaout viewParent,然后再在viewParent中添加真正的视图loadingLayout ,并控制loadingLayout的位置和宽高。

实际效果如下

DecorView与windowTranslucentStatus冲突解决_第2张图片
实际效果

发现有两处异常显示的问题

  • Actionbar与下面网络图片直接有一个间距
  • 底部黄色区域被遮盖住了一部分

这两个问题都是由于上面说的windowTranslucentStatus导致的。

通过分析发现,屏幕实际高度是1920px,displayMetrics.heightPixels=1812px,底部虚拟按键区域高度为108px,不在displayMetrics的区域内。

  viewParent = new LinearLayout(activity); 
  viewParent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
  ···
  decorView.addView(viewParent);

这段代码是在decorView(1920px高度)中添加一个与它一样宽高的viewParent,所有viewParent占据了整个屏幕的大小。而windowTranslucentStatus=true,底部虚拟按键区域上浮,导致底部区域被覆盖。
而由于

            int pointY = 0;
            if (anchorView != null) {
                int[] anchorLocation = new int[2];
                anchorView.getLocationInWindow(anchorLocation);
                pointY = anchorLocation[1] + anchorView.getHeight();
            }

            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(displayMetrics.widthPixels,displayMetrics.heightPixels - pointY);
            layoutParams.width = displayMetrics.widthPixels;
            layoutParams.height = displayMetrics.heightPixels - pointY;
            layoutParams.gravity = Gravity.BOTTOM;

            viewParent.removeView(loadingLayout);//先移除再添加,防止隐藏后,再次显示,导致loadingLayout重复添加
            //添加视图
            viewParent.addView(loadingLayout, layoutParams);

是想在viewParent的 displayMetrics的区域中添加一个loadingLayout,高度为displayMetrics.heightPixels - pointY。但是由于Gravity.BOTTOM+windowTranslucentStatus,导致本来预期的底部参考点由底部虚拟按键区域的顶部,变为屏幕的底部了,所以导致Actionbar与下面网络图片直接有一个间距,刚好是底部虚拟按键区域的高度108px。

解决方案

    viewParent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, displayMetrics.heightPixels));

在添加viewParent时,将其高度设置为displayMetrics.heightPixels,这样viewParent的底部刚好与虚拟区域的顶部对齐,这样就完美解决上面的问题了。

DecorView与windowTranslucentStatus冲突解决_第3张图片
Paste_Image.png

你可能感兴趣的:(DecorView与windowTranslucentStatus冲突解决)