解决使用BottomSheetDialog时状态栏变黑的问题

问题描述

当使用support里的design 库里的BottomSheetDialog时,在6.0的机器上当对话框弹出时系统状态栏会变黑,以下图所示:
这里写图片描述
一开始觉得是我用的姿式不对,试过对style配置状态栏颜色,配置其余可能影响到的属性都没成功,今天google了一下,发现应该是BottomSheetDialog自己实现的问题,见:https://code.google.com/p/android/issues/detail?id=202691。其中的一条评论认为应该是BottomSheetDialog使用的布局为MATCH_PARENT``MATCH_PARENT致使,并经过修改布局高度的方式解决了这个问题,见下面第一种解决方法:java

解决方法

第一种,修改布局高度

继承BottomSheetDialog并重写其protected void onCreate(Bundle savedInstanceState)方法,代码以下:android

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        int screenHeight = getScreenHeight(getOwnerActivity());
        int statusBarHeight = getStatusBarHeight(getContext());
        int dialogHeight = screenHeight - statusBarHeight;
        getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, dialogHeight == 0 ? ViewGroup.LayoutParams.MATCH_PARENT : dialogHeight);
    }

    private static int getScreenHeight(Activity activity) {
        DisplayMetrics displaymetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        return displaymetrics.heightPixels;
    }

    private static int getStatusBarHeight(Context context) {
        int statusBarHeight = 0;
        Resources res = context.getResources();
        int resourceId = res.getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            statusBarHeight = res.getDimensionPixelSize(resourceId);
        }
        return statusBarHeight;
    }

若是你和我同样是使用了BottomSheetDialogFragment的话,那么须要继承它并重写它的public Dialog onCreateDialog(Bundle savedInstanceState)方法,改成返回一个你重写后的Dialog对象:程序员

@Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new YourBottomSheetDialog(getContext(), getTheme());
    }

解决后的效果是这样的:
这里写图片描述markdown

解决了状态栏变成黑色的问题,而且也没带来新的问题,能够说是完美解决。ide

第二种,添加FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS标志

第二种解决方法是在返回对话框以前,对Window添加一个FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS标志位。它一样是须要继承BottomSheetDialogFragment,并重写如下方法:布局

@Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        }
        return dialog;
    }

然而,在华为带虚拟导航栏的手机中运行起来会这样:
这里写图片描述ui

底部的内容被虚拟导航栏遮住了。这个方法不能采用。google

第三种,设置半透明状态栏

修改方法与第二种相似,代码以下:spa

@Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
        return dialog;
    }

结果以下:
这里写图片描述code

它也没什么问题,不过对于可以设置状态栏颜色的状况下,我仍是不喜欢顶部这种半透明的渐变。

总结

总结一下,第一种解决方法能够说是彻底知足个人要求。第二种解决方法在一些设备上有缺陷。第三种方法代码量一样也是最小的,不过它是设置顶部状态栏为半透明,这一点与我程序员其余地方在6.0系统上直接设置状态栏颜色的行为不一致,因此在项目中也不采用它。

参考资料:

《Show BottomSheetDialogFragment changes status bar color to black》

相关文章
相关标签/搜索