Blankj / AndroidUtilCode

:fire: Android developers should collect the following utils(updating).
https://blankj.com/2016/07/31/android-utils-code/
Apache License 2.0
33.24k stars 10.67k forks source link

BarUtils工具类完善建议 #581

Closed XXQAQ closed 6 years ago

XXQAQ commented 6 years ago

在开发中发现一种无需手动设置状态栏颜色即可适配的万能方案,最重要可以使状态栏完全融入布局中,体验更佳,个人认为是状态栏沉浸的最佳方案。

大概思路是:首先设置状态栏为透明色并将状态栏设置为FULLSCREEN | STABLE,不过如果只这样做会导致状态栏落在顶部View(Toolbar)上,所以还需要修改您的addHeightEqualStatusBarHeight方法,设置最顶部View(Toolbar)的paddingTop属性而非marginTop,这样就可以让您的状态栏直接被最顶部View的内容所填充,达到了完美的沉浸体验。

/**
 * Set the content layout full the StatusBar, but do not hide StatusBar.
 */
public static void setStatusBarFull(Activity activity) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        Window window = activity.getWindow();
        View decorView = window.getDecorView();
        decorView.setSystemUiVisibility(decorView.getSystemUiVisibility()
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(Color.TRANSPARENT);
    }
}

/**
 * Set the content layout full the NavigationBar, but do not hide NavigationBar.
 */
public static void setNavBarFull(Activity activity) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        Window window = activity.getWindow();
        View decorView = window.getDecorView();
        decorView.setSystemUiVisibility(decorView.getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setNavigationBarColor(Color.TRANSPARENT);
    }
}

/**
 * Add the top margin size equals status bar's height for view.
 *
 * @param view The view.
 */
public static void addHeightEqualStatusBarHeight(@NonNull View view) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
    {
        Object haveSetOffset = view.getTag(TAG_OFFSET);
        if (haveSetOffset != null && (Boolean) haveSetOffset) return;
        ViewGroup.LayoutParams lp = view.getLayoutParams();
        lp.height += getStatusBarHeight();
        view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + getStatusBarHeight(),
                view.getPaddingRight(), view.getPaddingBottom());
        view.setTag(TAG_OFFSET, true);
    }
}

=================================================================== //使用demo(建议在BaseActivity中使用) private void hideSystemBar() { BarUtils.setStatusBarFull((Activity) getContext()); if (toolbar != null) //非Toolbar的布局不需要使状态栏抬高 BarUtils.addHeightEqualStatusBarHeight(toolbar); }

Blankj commented 6 years ago

你考虑得太少啦,首先都是兼容到 API 19 的,你直接 21 这就不对了,然后为什么非 toolbar 就不需要抬高状态栏了,这没有必然联系,还有就是你这样只是考虑了 Activity,如果 viewPage + fragment 这样的状态栏呢,还有 DrawLayout。

也许对你来说你现在写的可能是足够了哈,但场景太多了,所以要考虑更多的因素,marginTop 和 paddingTop 其实没有什么大差别,但是我之前考虑到 paddingTop 的化 background 会呈现到 paddingTop 中,所以就选择了 marginTop,如果还有疑问可以试着把我 Demo 里的功能都做到再来优化也可以哈。

XXQAQ commented 6 years ago

blibli的方案就是如此所以blibi应用场景很简单?这个不仅完美兼容drawlayout,tablayout+viewpager,包括CollaspingToolbarLayout或者fragment都没有一点问题。你试一下就知道行不行了,至于你说toolbar之外的布局为什么不需要设置padding。看看ios的沉浸效果就明白了,其实没有Toolbar的布局几乎都不需要状态栏单独显示的,把状态栏沉浸到布局中体验会更好

Blankj commented 6 years ago

那光 viewPager 和 fragment 呢,我 demo 里有这效果的,你这能实现? bilibili 是符合你说的效果,但它又不是囊括了所有情况,天下之大无奇不有,你这可能是满足大部分需求了,但那些超出你范围的呢,你这套就不好使了哈。

XXQAQ commented 6 years ago

screenshot_2018-08-09-09-50-43-001_com qiyingli m screenshot_2018-08-09-09-50-45-337_com qiyingli m screenshot_2018-08-09-09-50-48-060_com qiyingli m

我上个App的应用场景就是Viewpager+N个Fragment,这个是没问题的

Blankj commented 6 years ago

大哥 看下我 demo 的效果可以吗,你这是点击下面图标来切换 viewpager 的,我说的是滑动的情况