博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
沉浸式探索
阅读量:4180 次
发布时间:2019-05-26

本文共 4730 字,大约阅读时间需要 15 分钟。

        目前市场上的好多应用都已经使用了沉浸式,实现方式可以有多中,其中在主题中可以设置两个属性:

 
//这两个属性默认都是false,//windowTranslucentStatus指的是状态栏是半透明,//当这个值为false时,可以设置statusBarColor的颜色,//当为true时,statusBarColor不起作用,内容会处于状态栏(半透明)的下面
true
//windowTranslucentNavigation指的是导航栏的半透明//当这个值为false时,可以设置navigationBarColor的颜色//当这个值为true时,navigationBarColor不起作用,内容会处于导航栏(半透明)和状态栏下面
true
#ff0000
#ff0000

当需要把状态栏的半透明换成和底背景一样时,只需要把windowtranslucentStatus改成false或是去掉即可,这两个属性是在PhoneWindow中获取并设置的,让我们来看一下generateLayout(DecorView decor)(这个方法是在setContentView()中被调用到的)这个方法是如何设置的:

if (a.getBoolean(R.styleable.Window_windowTranslucentStatus,        false)) {    setFlags(FLAG_TRANSLUCENT_STATUS, FLAG_TRANSLUCENT_STATUS            & (~getForcedWindowFlags()));}if (a.getBoolean(R.styleable.Window_windowTranslucentNavigation,        false)) {    setFlags(FLAG_TRANSLUCENT_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION            & (~getForcedWindowFlags()));}
其实就是调用了Window的setFlags()方法,还有上面设置的颜色也是在这里获取的

if (!mForcedStatusBarColor) {    mStatusBarColor = a.getColor(R.styleable.Window_statusBarColor, 0xFF000000);}if (!mForcedNavigationBarColor) {    mNavigationBarColor = a.getColor(R.styleable.Window_navigationBarColor, 0xFF000000);}

这里获取到颜色后会在DecorView中进行设置,

private int calculateStatusBarColor() {    return calculateStatusBarColor(mWindow.getAttributes().flags,            mSemiTransparentStatusBarColor, mWindow.mStatusBarColor);}public static int calculateStatusBarColor(int flags, int semiTransparentStatusBarColor,        int statusBarColor) {    return (flags & FLAG_TRANSLUCENT_STATUS) != 0 ? semiTransparentStatusBarColor            : (flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0 ? statusBarColor            : Color.BLACK;}

这里就是决定statusBarColor的颜色到底是哪一个。

        对于这里的所有设置都可以在代码中进行设置,具体的可以查看郭霖的这一篇。

        不管是在代码中设置还是在主题中设置,最后决定权还是在DecorView这里,

WindowInsets updateColorViews(WindowInsets insets, boolean animate) {    WindowManager.LayoutParams attrs = mWindow.getAttributes();    //主题中设置的系统UI属性在这里可以获取 attrs.systemUiVisibility    //代码中设置的系统UI属性在这里可以获取 getWindowSystemUiVisibility()    int sysUiVisibility = attrs.systemUiVisibility | getWindowSystemUiVisibility();        ...        // When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, we still need    // to ensure that the rest of the view hierarchy doesn't notice it, unless they've    // explicitly asked for it.    boolean consumingNavBar = (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0                    && (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0                    && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0                    || mLastShouldAlwaysConsumeNavBar;    // If we didn't request fullscreen layout, but we still got it because of the    // mForceWindowDrawsStatusBarBackground flag, also consume top inset.    boolean consumingStatusBar = (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) == 0            && (sysUiVisibility & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0            && (attrs.flags & FLAG_LAYOUT_IN_SCREEN) == 0            && (attrs.flags & FLAG_LAYOUT_INSET_DECOR) == 0            && mForceWindowDrawsStatusBarBackground            && mLastTopInset != 0;    int consumedTop = consumingStatusBar ? mLastTopInset : 0;    int consumedRight = consumingNavBar ? mLastRightInset : 0;    int consumedBottom = consumingNavBar ? mLastBottomInset : 0;    int consumedLeft = consumingNavBar ? mLastLeftInset : 0;    if (mContentRoot != null            && mContentRoot.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {        ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) mContentRoot.getLayoutParams();        if (lp.topMargin != consumedTop || lp.rightMargin != consumedRight                || lp.bottomMargin != consumedBottom || lp.leftMargin != consumedLeft) {            lp.topMargin = consumedTop;            lp.rightMargin = consumedRight;            lp.bottomMargin = consumedBottom;            lp.leftMargin = consumedLeft;            mContentRoot.setLayoutParams(lp);            if (insets == null) {                // The insets have changed, but we're not currently in the process                // of dispatching them.                requestApplyInsets();            }        }        if (insets != null) {            insets = insets.replaceSystemWindowInsets(                    insets.getSystemWindowInsetLeft() - consumedLeft,                    insets.getSystemWindowInsetTop() - consumedTop,                    insets.getSystemWindowInsetRight() - consumedRight,                    insets.getSystemWindowInsetBottom() - consumedBottom);        }    }    if (insets != null) {        insets = insets.consumeStableInsets();    }    return insets;}
从这里可以看出,沉浸式其实就是根据设置的属性计算内容所占的空间大小。

你可能感兴趣的文章
菜鸟文科生的java之路:流程控制语句
查看>>
北海糖:Java初阶练习题
查看>>
不知道什么是数组?看这里就好了
查看>>
文科生北海唐的Java之路:方法(慕课)
查看>>
自学Java的轨迹线路
查看>>
如何更好的隐藏你自己,让我们谈谈什么是封装?
查看>>
文科生北海糖的:Java之路——继承
查看>>
Makefile 中:= ?= += =的区别
查看>>
消灭编译警告(Warning)
查看>>
(GCC) How can I hide "defined but not used" warnings in GCC?
查看>>
错误: 隐式声明函数‘kmalloc’ [-Werror=implicit-function-declaration]
查看>>
error: two or more data types in declaration specifiers原因及解决方法
查看>>
Linux驱动基础开发2
查看>>
ioctl在socket中的一些用法及示例
查看>>
Linux设备驱动--块设备(二)之相关结构体
查看>>
Linux设备驱动--块设备(四)之“自造请求”
查看>>
Nand Flash和Nor Flash相关知识
查看>>
NAND flash和NOR flash的区别
查看>>
writeb(), writew(), writel(),readb(), readw(), readl() 宏函数
查看>>
NOR Flash擦写和原理分析
查看>>