1. 程式人生 > >Android 側邊欄NavigationView與toolbar

Android 側邊欄NavigationView與toolbar

最近做的一個專案,使用了側邊欄,按著官網的教程,使用的DrawerLayout,然後也用到了actionbar,然後顯示效果如下:
這裡寫圖片描述
(該之前的圖懶得還原了。。這個是示意圖)

但是我發現Google 商店之類的應用,側邊欄是這樣的
這裡寫圖片描述

這兩個的區別是側邊欄是否延伸到系統頂部。
難道谷歌的應用用的不是DrawerLayout?
到知乎上轉了一圈也沒有找到明確答案,關於這兩種樣式爭論也不少,我是傾向於google商店這種樣式。

在官網文件那下了個DrawerLayout例子,結果也是這樣的
這裡寫圖片描述

沒辦法,本來想新建個工程在研究下DrawerLayout樣式的,結果發現新建工程的模板裡有個這個
這裡寫圖片描述


果斷選了跑起來看看,果然不負我所望
這裡寫圖片描述
趕快研究下他的原始碼
先看了下佈局檔案

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id
="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start">
<include layout="@layout/app_bar_main" android:layout_width="match_parent" android:layout_height="match_parent"
/>
<android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header_main" app:menu="@menu/activity_main_drawer" /> </android.support.v4.widget.DrawerLayout>

根據DrawerLayout的說明,其佈局包含兩個元素,一個顯示的主介面,另一個就是側邊欄,那麼下邊這個android.support.design.widget.NavigationView應該就時這裡的側邊欄了,我之前在這按照官網例子用的是一個listview,難道是因為這個導致效果不一樣?
於是我把這個控制元件粘到了我的工程裡,結果執行之後,效果就是第一張圖的樣子,依舊在導航欄的下邊,看來不是這個問題。

然後又看了下原始碼,發現裡邊使用了toolbar而不是actionbar,這個之前在其他文件裡看過。說是之後都拋棄了actionbar然後使用更靈活的toolbar了。難道是因為這個,然後看了下主題發現是NoActionBar。然後想到一種可能性,actionbar作為系統標題欄,不會被佈局裡的控制元件覆蓋掉,而使用toolbar,因為其屬於佈局中一個控制元件,可以被覆蓋,然後才成為了那個效果?
測試一下,把我的工程的主題改為了NoActionBar後,效果如下:
這裡寫圖片描述

基本差不多了,不過上邊狀態列處沒有延伸到
解決方法時給DrawerLayoutNavigationView 設定android:fitsSystemWindows="true" ,這句話的作用是使控制元件能到擴充套件到狀態列下,實現沉浸式的效果。修改之後的最終效果如下:

這裡寫圖片描述
果然成了!
側邊欄這下是解決了,不過接下來重新實現toolbar了。

學習下例子工程的原始碼,toolbar的佈局在app_bar_main.xml裡

這裡邊用到的CoordinatorLayout,略微搜了下,是Material Design中新增的佈局控制元件,支援一些浮動的效果,今天先不研究。
toolbar程式碼如下:

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

AppBarLayout是一個用來盛放toolbar的佈局,在其內部的元素都會當做toolbar組合在一起。不用AppBarLayout直接使用Toolbar也是可以的。在這裡AppBarLayout主要作用是控制toolbar中文字與控制元件顏色。

佈局完成後,只需在對應activity中加入以下幾行程式碼即可

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

然後還需要注意下activity的主題樣式,如果不注意可能會出現這個樣子
這裡寫圖片描述
(頂部白色透明)

避免出現這個問題要注意一下幾點:

  1. 對於包含抽屜的DrawerLayout的activity,佈局檔案中,需要設定 android:fitsSystemWindows="true"DrawerLayout與NavigationView,保證其能延伸到狀態列。

  2. 對於其他正常的activity,單獨使用Theme.AppCompat.Light.NoActionBar主題即可

  3. 對於包含抽屜的DrawerLayout的activity,為了在5.0之上顯示沉浸式效果,需要建立values-v21\styles.xml,只對5.0之上系統起作用。

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>

    </style>

對於2,3點說的不是很清楚,大家看過原始碼應該就能明白了,主要看看每個activity的主題有什麼區別。
原始碼地址