使用SystemBarTint搭配NavigationView在Android4.4以上实现透明状态栏

勇敢的少年啊,快来看看什么叫做抽屉导航之美吧~

女神镇楼

前言

在Android中,很多App的主界面都使用了抽屉式导航,比如网易云音乐、Fuubo、Bilibili等,就我个人而言,我是非常喜欢这种导航方式的,顺便吐槽一下新版知乎,导航模式改为了底部导航,还取消了滑动返回,用的心累。

抽屉式导航

这是官方给出的示例图片,我觉得非常的漂亮,尤其是抽屉导航在状态栏的下方,当滑动抽屉的时候可以很明显的看出状态栏与抽屉之间的层次关系,而这也是今天我们要实现的效果,以下示例都运行在4.4版本上。

实现

首先看两个比较关键的属性,一个是:windowTranslucentStatus这个属性支持的API最低为19,通常定义在values-v19/styles.xml下,它的作用是可以将状态栏的颜色置为透明色,还有一个是fitsSystemWindows,这个属性的作用是确保内容不会显示到系统窗口下面,这里的系统窗口指的是StatusBar和NavigationBar。

全透明状态栏

首先看看网易云音乐在4.4上的表现

网易云音乐

可以看到抽屉是在状态栏下面的,并且状态栏是完全透明的,要实现这样的效果也是很简单的,使用Toolbar替换ActionBar,在values-v19/styles.xml和values-v21/styles.xml中定义windowTranslucentStatus为true。
代码如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="AppTheme" parent="AppTheme.Base">
        <item name="android:windowTranslucentStatus">true</item>
    </style>
</resources>

activity_main代码:

<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/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="false">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <include layout="@layout/toolbar" />

        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="false"
        app:headerLayout="@layout/drawer_header"
        app:menu="@menu/menu_drawer" />
</android.support.v4.widget.DrawerLayout>

要注意的是设置fitsSystemWindows为false。
其实到这里就已经实现了这个效果,不过可以发现toolbar会向上移动,有一部分被状态栏遮住,其实遮住的这一部分就是状态栏的高度,因为设置为true会,解决办法是可以在Activity中为toolbar添加顶部的padding,代码如下:

public class MainActivity extends AppCompatActivity {

    private Toolbar mToolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);
        mToolbar.setPadding(0,getStatusBarHeight(),0,0);
    }

    public int getStatusBarHeight() {
        int result = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }
}

最终效果:


着色状态栏

这种抽屉方式,在滑动的时候给人一种撕裂的感觉,看起来不是很舒服。

Bilibili

因为要给statusbar着色,所以要用到第三方库SystemBarTint,但要注意这个库已经被作者标记为DEPRECATED,即作者不赞成现在使用该库,这个与今天主题无关,就不多管了。
Android4.4(Kitkat)提出了透明状态栏的概念,可以为status bar或是Navigation bar 设置透明度,而SystemBarTint的出现使我们更加方便为status bar和 Navigation bar着色,可以设置color或是Drawable。
首先必须允许status bar 透明,在values-v19/styles.xml中添加
<item name="android:windowTranslucentStatus">true</item>
activity_main代码与上一个基本相同,只是不再需要fitsSystemWindows属性。
Activity代码:

public class MainActivity extends AppCompatActivity {

    private Toolbar mToolbar;
    private SystemBarTintManager mTintManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);
        mToolbar.setPadding(0, getStatusBarHeight(), 0, 0);
        setTintManager();
    }

    @TargetApi(19)
    private void setTintManager() {
        mTintManager = new SystemBarTintManager(this);
        mTintManager.setStatusBarTintEnabled(true);
        mTintManager.setStatusBarTintColor(Color.parseColor("#2196F3"));
    }
    
    ...
}

最终效果:


带透明度的状态栏

这种其实就是实现官方给出的那种效果,也需要搭配SystemBarTint,代码与相当于是上面两种的结合,只不过在设置statusbar颜色的时候设置的是#20000000,即使透明度为20%;

@TargetApi(19)
    private void setTintManager() {
        mTintManager = new SystemBarTintManager(this);
        mTintManager.setStatusBarTintEnabled(true);
        mTintManager.setStatusBarTintColor(Color.parseColor("#20000000"));
    }

最终效果:


参考

Android and the transparent status bar
该使用 fitsSystemWindows 了!

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

推荐阅读更多精彩内容