zoukankan      html  css  js  c++  java
  • Android中沉浸式状态栏的应用

    在Android5.0版本后,谷歌公司为Android系统加入了很多新特性,刷新了Android用户的体验度。而其中的一个新特性就是沉浸式状态栏。那么问题来了,很多非移动端的小伙伴就要问了,什么是沉浸式状态栏?传统的手机状态栏是呈现出黑色条状的,有的和手机主界面有很明显的区别。这样就在一定程度上牺牲了视觉宽度,界面面积变小。而沉浸式状态栏将状态栏的颜色变为透明,并将原有的布局沾满了手机屏幕,使得状态栏和手机布局内容融为一体。下面,我们来详细的说明沉浸式状态栏在项目中的实际应用。

    要在当前的Activity界面实现沉浸式,首先我们要在oncreate方法中写入如下代码:

    getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    Window window = getWindow();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
       window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                        | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
       window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
       window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
       window.setStatusBarColor(Color.TRANSPARENT);
       window.setNavigationBarColor(Color.TRANSPARENT);
    }

    这样代码就可以实现沉浸式状态。由于沉浸式状态栏只支持5.0以上手机,所以我们在这里进行了版本判断。不过实际操作中,有小伙伴又遇到了新的问题。有些有虚拟按键的也被沉浸了,这个就会很郁闷了。我们的构思是布局中有一个黑色的view,在有虚拟按键的手机上显示出来,并且高度与虚拟按键一致。具体操作如下。

    检查是否具有虚拟按键

    public static boolean hasNavBar(Context context) {
            Resources res = context.getResources();
            //这种方式一定要注意写法要正确,内部应该是通过反射去调用的。
            int resourceId = res.getIdentifier("config_showNavigationBar", "bool", "android");
            if (resourceId != 0) {
                boolean hasNav = res.getBoolean(resourceId);
                // check override flag
                String sNavBarOverride = getNavBarOverride();
                if ("1".equals(sNavBarOverride)) {
                    hasNav = false;
                } else if ("0".equals(sNavBarOverride)) {
                    hasNav = true;
                }
                return hasNav;
            } else { // fallback
                if (Build.VERSION.SDK_INT >= 14) {
                    return !ViewConfiguration.get(context).hasPermanentMenuKey();
                } else {
                    return false;
                }
            }
        }

    判断虚拟按键栏是否重写

    private static String getNavBarOverride() {
            String sNavBarOverride = null;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                try {
                    Class c = Class.forName("android.os.SystemProperties");
                    Method m = c.getDeclaredMethod("get", String.class);
                    m.setAccessible(true);
                    sNavBarOverride = (String) m.invoke(null, "qemu.hw.mainkeys");
                } catch (Throwable e) {
                }
            }
            return sNavBarOverride;
        }

    获取虚拟按键栏高度

    public static int getBottomStatusHeight(Context context) {
            int totalHeight = getDpi(context);
    
            int contentHeight = getScreenHeight(context);
    
            return totalHeight - contentHeight;
        }

    获取屏幕高度

     public static int getScreenHeight(Context context) {
            WindowManager wm = (WindowManager) context
                    .getSystemService(Context.WINDOW_SERVICE);
            DisplayMetrics outMetrics = new DisplayMetrics();
            wm.getDefaultDisplay().getMetrics(outMetrics);
            return outMetrics.heightPixels;
        }
    获取屏幕原始尺寸高度,包括虚拟功能键高度
    public static int getDpi(Context context) {
            int dpi = 0;
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            Display display = windowManager.getDefaultDisplay();
            DisplayMetrics displayMetrics = new DisplayMetrics();
            @SuppressWarnings("rawtypes")
            Class c;
            try {
                c = Class.forName("android.view.Display");
                @SuppressWarnings("unchecked")
                Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
                method.invoke(display, displayMetrics);
                dpi = displayMetrics.heightPixels;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return dpi;
        }

    代码中设置布局中View的高度

    if (hasNavBar(this)) {
                bottomView.getViewTreeObserver().addOnGlobalLayoutListener(
                        new ViewTreeObserver.OnGlobalLayoutListener() {
                            // 当layout执行结束后回调此方法
                            @Override
                            public void onGlobalLayout() {
                                LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) bottomView.getLayoutParams();
                                params.height = getBottomStatusHeight(ActivityShopIndex.this);
                                bottomView.setLayoutParams(params);
                                bottomView.setVisibility(View.VISIBLE);
                            }
                        });
            }

    这样我们就成功将虚拟按键栏也被沉浸的问题解决了。

    作者 水木

  • 相关阅读:
    基于docker的MongoDB复制(副本集)
    (已解决)ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib
    【洛谷3530】[POI2012] FES-Festival(差分约束+Tarjan)
    【洛谷4765】[CERC2014] The Imp(贪心+DP)
    【洛谷7093】[CERC2014] Can't stop playing(搜索)
    【CF755G】PolandBall and Many Other Balls(倍增FFT)
    【洛谷3896】[湖南集训] Clever Rabbit(搜索)
    【洛谷7215】[JOISC2020] 首都(点分治+BFS)
    【BZOJ4173】数学(欧拉函数)
    【洛谷5748】集合划分计数(多项式exp)
  • 原文地址:https://www.cnblogs.com/widgetbox/p/7761841.html
Copyright © 2011-2022 走看看