透明statusbar的一些小建议

大家都知道android4.4出现了沉浸式状态栏一说,5.0以上则是透明状态栏,其实呢都是透明状态栏。最近公司要求实现的就是有一个viewpager在statusbar底下和design support的DrawerLayout的,也是被这个问题困扰了好一会儿.看了很多网上的文章,还是没有把4.4和5.0的效果统一起来,于是用了一些土方法(大致统一,当然我们知道是不可能完美统一的,4.4的透明状态栏会有一层透明度渐变的遮罩,看起来就是所谓的沉浸式状态栏了)

4.4与5.0的透明状态栏的区别

android4.4的时候

android4.4未处理

可以通过给window设置属性达到让屏幕延伸到全屏的目的,可以使用以下两种方式:

给activity设置theme:(v-19)

<style name="TranslucentStatus" parent="AppTheme">    
<item name="android:windowTranslucentStatus">true</item>
</style>
4.4设置theme

activity中onCreate的setContentView之前:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
    Window window = getWindow();
    window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
      WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
}
4.4代码设置

android5.0的时候


5.0未处理

网上的blog对5.0以上的说的比较乱,或者说我没有把大家写的blog思路理清,现在自己来整理一遍:

第一种方法,和4.4的处理一模一样,参考上述代码,效果如下:

5.0方式1

这种方式会出现一层遮罩,可能有些小伙伴就不开心了,这黑黑的

莫慌,抱紧我,还有另一种方式,通过java代码:

if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP){    
  Window window = getWindow();    
  //下面这一行呢是android4.0起推荐大家使用的将布局延伸到状态栏的代码,配合5.0的设置状态栏颜色可谓天作之合
  window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN            
                                              | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);   
  window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUND); 
  window.setStatusBarColor(Color.TRANSPARENT);
}

效果如下:

5.0方式2

当然啦,某些小伙伴脑洞打开,于是想利用这样的方式去除4.4设备上的那层渐变的遮罩,于是我这里先做了实验,大家就别费功夫了,这个方式(不能设置状态栏颜色的情况下)的效果如下:

4.4layout_fullscreen

哦豁!很好,有些小伙伴还想起来了有个开源库叫SystemBarTint ,可以设置状态栏颜色,而且恰好是在4.4以上就有效果的,很棒,但是用这个库的第一条件就是开启透明状态栏,这岂不是得先做到上面说的4.4透明状态栏的设置了?但是只要能去除遮罩,这一切都是有回报的
于是我也实验了一遍,在代码中加入了如下设置:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { 
    Window window = getWindow(); 
    window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, 
                     WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN        
                                              | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
    SystemBarTintManager manager = new SystemBarTintManager(this);
    manager.setStatusBarTintEnabled(true);
    manager.setStatusBarTintColor(Color.TRANSPARENT);
}

4.4layout_fullscreen and systembartint

很遗憾,这个遮罩很顽强。

做个小结

4.4 利用FLAG_TRANSLUCENT_STATUS
5.0 则有两种方案,喜欢遮罩的参考4.4,不喜欢的参考方式2

很好,通过以上的代码,就可以将布局延伸到状态栏了,那么问题来了,状态栏和布局重叠了怎么办?

问题与解决

关于这个问题,用的最多的就是fitSystemWindows这个属性。给layout设置这个属性,作用是将该layout中的子布局放置在状态栏以下、底部按钮以上的位置。

假如是纯色的状态栏,很简单,给布局外面再套一个ViewGroup,然后给这个viewGroup设置fitSystemWindows属性和colorPrimaryDark颜色背景,这样原先的布局悉数位于正常位置,而本来透明的状态栏底下是colorPrimaryDark颜色而恰好变成我们需要的颜色。

假如不是纯色的状态栏,而是一个ViewPager或者ImageView之类的需要将图片延伸到状态栏底下的情况。那么就是别的需要fitSystemWindows的布局就设置一个,不需要的就不设置了,灵活运用fitSystemWindows。比如下面这个截图:

4.4给hello world加上linearlayout,再给linearlayout加上fitSystemWindows=true

还有另外一个简单直接的方法:设置paddingTop或者marginTop呀!
android6.0以下statusBar高度是25dp,6.0以上是24dp,给相应布局添加一个paddingTop(或者marginTop)就能完美解决问题,偷懒的话设置个25或者24,不偷懒一点直接判断系统版本再加,如下:

4.4给小android设置的marginTop = 25dp

还有一个比较特殊的情况,那就是navigation,也就是design support自带的侧滑,这里要用到一个ScrimInsertsFrameLayout,位于design包,比如我的代码如下:

<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"    
    xmlns:app="http://schemas.android.com/apk/res-auto"    
    android:id="@+id/drawerLayout"    
    android:layout_width="match_parent"    
    android:layout_height="match_parent">
    <android.support.design.widget.CoordinatorLayout        
        android:id="@+id/content"        
        android:layout_width="match_parent"        
        android:layout_height="match_parent"        
        android:fitsSystemWindows="true">        
        <TextView            
            android:layout_width="wrap_content"            
            android:layout_height="wrap_content"            
            android:text="hello world"            
            android:textSize="30sp" />    
    </android.support.design.widget.CoordinatorLayout>      
    <android.support.design.internal.ScrimInsetsFrameLayout        
        android:id="@+id/drawer"        
        android:layout_width="match_parent"        
        android:layout_height="match_parent"        
        android:layout_gravity="start"        
        android:background="@android:color/white"        
        app:insetForeground="#4000">        
        <ImageView            
            android:layout_width="wrap_content"            
            android:layout_height="wrap_content"            
            android:src="@mipmap/ic_launcher" />        
        <LinearLayout            
            android:layout_width="match_parent"            
            android:layout_height="match_parent"            
            android:layout_marginTop="24dp"            
            android:orientation="vertical">            
            <TextView                
                android:layout_width="wrap_content"             
                android:layout_height="wrap_content"                
                android:text="hello world"                
                android:textSize="30sp" />        
        </LinearLayout>    
    </android.support.design.internal.ScrimInsetsFrameLayout></android.support.v4.widget.DrawerLayout>

5.0是不需要做任何事情的,除了设置状态栏颜色为透明,有的小伙伴说一定要fitSystemWindows啦还有设置windowDrawsSystemBarBackgrounds=true啦之类的,其实是不要的,但是content的根布局一定要设置fitSystemWindows = true。

getWindow().setStatusBarColor(Color.TRANSPARENT);

或者

<item name="android:statusBarColor">@android:color/transparent</item>

效果如下:

5.0侧滑

当然,4.4还是要加透明状态栏的,参考最开始的步骤,效果如下:

4.4侧滑 透明状态栏

对于ScrimInsetsFrameLayout,有一个属性

app:insetForeground="#4000"

这个属性就是右滑罩在sattusbar上面的那一层颜色,也可以是drawable。有些大神说要重写ScrimInsetsFrameLayout类以使这个属性生效,可是我发现已经生效了,就不重写了。
还有一点呢,就是在ScrimInsetsFrameLayout里设置fitSystemWindows是无效的,想要UI正常,就得设置paddingTop(marginTop),上面两张截图就是给“hello world”设置了的。对于ScrimInsetsFrameLayout的fitSystemWindows这位大神这里做了很详细的分析

相信利用以上方法,小伙伴们一定对android状态栏的设置更加清晰了,可以尽量做到自己希望的效果了。可怜被我利用的android小机器人

Paste_Image.png

这篇文章的相关代码可以在我的github上面找到

本文中所有截图都是android studio自带的虚拟机上的效果截图,欢迎大家提建议吐槽指正。

参考文章:
Android 5.0 如何实现将布局的内容延伸到状态栏?
Android 沉浸状态栏

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351

推荐阅读更多精彩内容