沉浸式状态栏全屏使用时的问题

1,929 阅读2分钟

由于公司需要,把之前写过的ChangeStatusColor-Android项目有进行了改进,之前的项目已经支持了MIUI6+、Flyme4+和android6.0以上的字体颜色改变和android4.4以上的沉浸式状态栏。

请看下面两张图,这里的截图机型是小米4 MIUI7 Android6.0.1:

状态栏颜色为白色 状态栏颜色为黑
状态栏颜色为白色 状态栏颜色为黑色

之前如果横屏设置的不是全屏模式的话,横竖屏切换切换没有问题,但是横屏模式设置全屏模式后,android4.4到android5。0之间会发现标题栏会被状态栏遮挡住,就像图中的第一张图,真正我们想要的是第四张图,如下图所示:
image
原因在于之前在setStatusBarColor()方法中做了判断

/**
     * 修改状态栏颜色,支持4.4以上版本
     *
     * @param activity
     * @param colorId  直接使用资源ID,即R.color.xxx
     * @param isFollow 是否保持沉浸式状态
     */
    public static void setStatusBarColor(Activity activity, int colorId, boolean isFollow) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = activity.getWindow();
//      window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            if (!isFollow) {
                window.setStatusBarColor(colorId);
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //使用SystemBarTint库使4.4版本状态栏变色,需要先将状态栏设置为透明
            transparencyBar(activity);
            ViewGroup contentFrameLayout = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT);
            View parentView = contentFrameLayout.getChildAt(0);
            if (parentView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                parentView.setFitsSystemWindows(true);
            }
            tintManager = new SystemBarTintManager(activity);
            tintManager.setStatusBarTintEnabled(true);
            tintManager.setStatusBarTintColor(colorId);
            /*// set a custom tint color for all system bars
            tintManager.setTintColor(Color.parseColor("#99000FF"));
            // set a custom navigation bar resource
            tintManager.setNavigationBarTintResource(R.drawable.my_tint);
            // set a custom status bar drawable
            tintManager.setStatusBarTintDrawable(MyDrawable);*/
        }
    }

就是这句代码导致了上面的问题出现了

if (parentView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                parentView.setFitsSystemWindows(true);
            }

解决方案:

    /**
     *  设置WindowManager.LayoutParams.FLAG_FULLSCREEN时,由于使用了fitSystemWindows()方法,导致的问题
     *  支持4.4以上版本,在5.0以上可以不需要调用该方法了
     * @param activity
     * @param flag_fullscreen   true:添加全屏   false:清除全屏
     */
    public static void setFitsSystemWindows(Activity activity, boolean flag_fullscreen) {
        ViewGroup contentFrameLayout = (ViewGroup) activity.findViewById(Window.ID_ANDROID_CONTENT);
        View parentView = contentFrameLayout.getChildAt(0);
        if(flag_fullscreen){
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏
        }else {
            activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//清除全屏
        }
        if (parentView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH && Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP) {
            if (tintManager != null) {
                if (flag_fullscreen) {
                    tintManager.setStatusBarTintEnabled(false);
                } else {
                    tintManager.setStatusBarTintEnabled(true);
                }
            }
        }
    }

首先该方法仅对android4.4~android5.0之间有效,如果横竖屏切换,只要调用该方法就可以解决上图所说的问题了。
使用方式:
在onCreate()方法中调用

StatusBarUtil.setStatusBarColor(MainActivity.this, getResources().getColor(R.color.colorAccent), false);

如果在onCreate()方法中不起作用,可以把它放在onStart()方法中

    @Override
    protected void onStart() {
        super.onStart();
        StatusBarUtil.setStatusBarColor(mActivity, getResources().getColor(R.color.common_top_bar), false);
    }

追其原因是StatusBarUtil#setStatusBarColor()->SystemBarTintManager#SystemBarConfig,mStatusBarHeight = getInternalDimensionSize(res, STATUS_BAR_HEIGHT_RES_NAME);这句代码获取状态栏高度为0在onCreate()方法中。

如果要横竖屏切换,首先要在AndroidManifest.xml中Activity设置android:configChanges=”keyboardHidden|orientation|screenSize”

        <activity
            android:name=".MainActivity"
            android:theme="@style/NoActionBar"
            android:configChanges="keyboardHidden|orientation|screenSize">
        </activity>

然后重写onConfigurationChanged()方法

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {// 横屏
//            Log.e(TAG, "onConfigurationChanged: " + "横屏");

        } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
//            Log.e(TAG, "onConfigurationChanged: " + "竖屏");
        }
    }

手动切换横竖屏,项目中的代码案例,在切换的时候调用StatusBarUtil.setFitsSystemWindows()方法

mRadioGroupConfiguration.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, @IdRes int checkedId) {
                if (checkedId == R.id.rb_landscape){//横屏
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//                    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏
                    StatusBarUtil.setFitsSystemWindows(MainActivity.this, true);
                }else if(checkedId == R.id.rb_portrait){//竖屏
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);// 竖屏
//                    getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//清除全屏
                    StatusBarUtil.setFitsSystemWindows(MainActivity.this, false);
                }
            }
        });

最后送上解决后的效果图:

竖屏状态 横屏状态
竖屏状态 横屏状态