最近的项目中有用到设置状态栏透明,也就是做沉浸式状态栏,但是在实现的过程中也遇到了一些问题,所以在这里做个总结,同时寻求更好的解决方案。网上设置沉浸式状态栏的方式有好几种,以下是我采用的方法:

@TargetApi(19)
    public void transparencyBar(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = activity.getWindow();
            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);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            ViewGroup decorView = (ViewGroup)activity.getWindow().getDecorView();
            decorView.removeViewAt(decorView.getChildCount() - 1);
            ViewGroup rootView = (ViewGroup)((ViewGroup)activity.findViewById(android.R.id.content)).getChildAt(0);
            rootView.setFitsSystemWindows(false);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            rootView.requestLayout();
        }
        AndroidBug5497Workaround.assistActivity(this);
    }



        同时要在布局文件里设置根布局android:fitsSystemWindows="false"。这种方式适合商城类详情页面,上面是图片,整个是一个scrollview。

        第一个问题就是如果布局下方有edittext的话,当其获得焦点的时候,布局不会自动调整,有时会出现小键盘挡住edittext,用户体验不好。所以在上一段代码的最后引入了AndroidBug5497Workaround这个类。关于这个类的源码可查看:AndroidBug5497Workaround。引入后即可自动调整布局。注意:最后一句代码需与沉浸式状态栏一起设置,不可单独设置,否则自动调整的高度会有问题。

        第二个问题是有的手机(例如华为)底部会有虚拟按键,上述的代码会使虚拟按键变成透明,并会挡住下面的布局。这个时候可以将window.setNavigationBarColor(Color.TRANSPARENT);这句代码注释掉,虚拟按键就不会变色了。关于虚拟按键挡住布局以及小键盘弹出时不调整布局其实都是因为android:fitsSystemWindows="false"引起的,但是改为true呢又会使顶部状态栏变回去。对于虚拟按键的问题,我选择了判断当前页面是否有虚拟按键,如果有点话就给被挡住的布局设置一个底部的padding,高度为虚拟按键的高度,没有虚拟按键的话就不处理。以下为我采用的判断是否有虚拟按键的代码:

/**
     * 判断底部navigator是否已经显示
     * @param windowManager 当前activity的windowManager(getWindowManager)
     * @return 是否有虚拟按键
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    public boolean hasSoftKeys(WindowManager windowManager){
        Display d = windowManager.getDefaultDisplay();

        DisplayMetrics realDisplayMetrics = new DisplayMetrics();
        d.getRealMetrics(realDisplayMetrics);

        int realHeight = realDisplayMetrics.heightPixels;
        int realWidth = realDisplayMetrics.widthPixels;

        DisplayMetrics displayMetrics = new DisplayMetrics();
        d.getMetrics(displayMetrics);

        int displayHeight = displayMetrics.heightPixels;
        int displayWidth = displayMetrics.widthPixels;
        bottomHeight = realHeight - displayHeight;

        return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0;
    }



        其中bottomHeight就是虚拟按键的高度,可以存成常量并设置padding。这样设置之后就可以适配有虚拟按键的机型了。对于这些问题可能有更好的解决方案,我的方案也是从网上获取,希望能够帮到掉到坑里的同学。