Toolbar + DrawerLayout 初體驗(yàn)

本文原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處。
歡迎關(guān)注我的 簡(jiǎn)書(shū) ,關(guān)注我的專題 Android Class 我會(huì)長(zhǎng)期堅(jiān)持為大家收錄簡(jiǎn)書(shū)上高質(zhì)量的Android相關(guān)博文。

寫(xiě)在前面:
因?yàn)閯倓偖厴I(yè)不久,面對(duì)編程世界中快速的知識(shí)更迭、龐大的知識(shí)體系,總覺(jué)得有心無(wú)力。想學(xué)的東西很多,想實(shí)踐的技術(shù)很多,但是感覺(jué)始終處在追追趕趕的狀態(tài)中。終于到了周末,拿出來(lái)這非常難得的大塊時(shí)間,做一次知識(shí)總結(jié)和技術(shù)實(shí)踐。

最近公司在重構(gòu)代碼,包括UI布局這塊也是,打算采用 DrawerLayout + Toolbar + Statusbar 這種形式展示出來(lái)。說(shuō)來(lái)慚愧,其實(shí)這三個(gè)組件出來(lái)很久了,也看過(guò)一些資料,不過(guò)忘記是從哪里看到過(guò)一句話,那就是“沒(méi)有敲過(guò)的代碼永遠(yuǎn)不屬于自己,并且也不要指望能找到一行都不需要修改的代碼”,我非常認(rèn)同這句話,所以今天要一步一步的實(shí)現(xiàn)上述界面及功能。

新建項(xiàng)目

我們來(lái)在最新版的 Android Studio 中,新建一個(gè) module ,項(xiàng)目類型選第一個(gè),帶默認(rèn) FloatingActionButton 的這個(gè)。

來(lái)看看默認(rèn)的 xml 布局的樣子:

activity_main

布局文件的名字仍然是讓人熟悉的 activity_main ,不過(guò)港真...里面這些組件的名字也許有的是你第一次才見(jiàn)到,不過(guò)沒(méi)關(guān)系,我們一會(huì)來(lái)一個(gè)個(gè)的學(xué)習(xí)下它們,在此之前呢,來(lái)看看通過(guò) include 引入的這個(gè)布局 content_main

content_main

這個(gè)就好眼熟了對(duì)吧,以前我們創(chuàng)建一個(gè) empty activity 時(shí),這個(gè)布局就是 activity_main,現(xiàn)在它作為子布局,被 include 進(jìn)入了現(xiàn)在的 MainActivity 的布局中,這里想提一下,其實(shí) include 標(biāo)簽是可以作為布局優(yōu)化的一種方式,能讓你的代碼更整潔,便于管理。

現(xiàn)在運(yùn)行一下項(xiàng)目,看看整體的樣子如何:

Wiget Demo

如果你的公司項(xiàng)目上面的標(biāo)題欄部分還在手工寫(xiě),那未免也太跟不上時(shí)代了,原生的如此美觀,體驗(yàn)也如巧克力入口一般絲滑,所以趕緊換成原生的吧~

組件介紹

回過(guò)頭來(lái)看看新建項(xiàng)目中的我們可能還不認(rèn)識(shí)的組件,我來(lái)給大家做一個(gè)簡(jiǎn)略的介紹。

CoordinatorLayout

CoordinatorLayout 是一個(gè)頂層布局,繼承自 ViewGroup ,并且它可以通過(guò) Behavior 來(lái)控制子 View 的各種狀態(tài),來(lái)實(shí)現(xiàn)炫酷的效果,如果未來(lái)你想用 MD 的風(fēng)格來(lái)設(shè)計(jì)你的 app ,CoordinatorLayout 是你必須要接觸的。

CoordinatorLayout介紹及使用--張興業(yè)

AppBarLayout

AppBarLayout 是 MD 設(shè)計(jì)中,作為頂頭 Bar 的父布局出現(xiàn)的,它的存在可以實(shí)現(xiàn)多種炫酷的效果,這里不再詳細(xì)描述,需要使用自行查詢。

Toolbar

Toolbar 本身是代替 ActionBar 出現(xiàn)的控件,具有更靈活,可定制性更強(qiáng)的屬性,如果你的 app 需要一個(gè)導(dǎo)航欄,那目前 Toolbar 就是不二之選,Toolbar 也是我們今天的主角之一。

搭建 Toolbar

千里之行,始于足下,我們最先來(lái)搭建 Toolbar 好了。

在此之前一定要記住,如果想使用這些組件并且向下兼容它們,要在 gradle 文件中引入兩個(gè)必要的庫(kù):

    compile 'com.android.support:appcompat-v7:24.2.0'
    compile 'com.android.support:design:24.2.0'

效果很簡(jiǎn)單,來(lái)看看gif圖:

搭建Toolbar

首先我們?cè)?layout 文件夾下 新建一個(gè) xml 文件,名字叫:common_toolbar

代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:toolbar="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    toolbar:title="@string/author_name"
    toolbar:navigationIcon="@mipmap/ic_toolbar_navigation"
    app:popupTheme="@style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>

接下來(lái)解釋一下屬性
為了防止我們?cè)O(shè)置 toolbar 的屬性無(wú)效,需要加上自定義的命名控件:

xmlns:toolbar="http://schemas.android.com/apk/res-auto"

這樣在 xml 中設(shè)置 toolbar:title toolbar:navigationIcon 等才會(huì)生效(這是一個(gè)無(wú)愛(ài)的 bug)

toolbar:title 是上面的 Melo 字樣,代表 Toolbar 的標(biāo)題
toolbar:navigationIcon 是 Melo 左側(cè)的抽屜按鈕,一會(huì)我們通過(guò)它來(lái)點(diǎn)開(kāi)抽屜

接下來(lái)配置 Toolbar 右側(cè)三個(gè)點(diǎn)的菜單
在 menu 文件夾下 創(chuàng)建 menu_main.xml,代碼如下:

<menu 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"
    tools:context="com.melo.blog.wigetdemo.MainActivity">
    <item
        android:id="@+id/action_settings"
        android:orderInCategory="1"
        android:title="@string/action_settings"
        app:showAsAction="never" />

    <item
        android:id="@+id/action_about"
        android:orderInCategory="2"
        android:title="@string/action_about"
        app:showAsAction="never" />

    <item
        android:id="@+id/action_share"
        android:orderInCategory="3"
        android:title="@string/action_share"
        app:showAsAction="never" />

    <item
        android:id="@+id/action_like"
        android:orderInCategory="4"
        android:title="@string/action_like"
        app:showAsAction="never" />

    <item
        android:id="@+id/action_collect"
        android:orderInCategory="5"
        android:title="@string/action_collect"
        app:showAsAction="never" />

</menu>

這個(gè)沒(méi)什么太多介紹的,不懂的屬性自行查詢一下就可以解了。
將 Toolbar include 進(jìn) activity_main 的布局中:

include

接著 MainActivity 中尋找 Toolbar ,并且為右上方菜單設(shè)置點(diǎn)擊事件:

package com.melo.blog.wigetdemo;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements Toolbar.OnMenuItemClickListener {

    private Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initView();
        initListener();
    }

    private void initView() {
        setContentView(R.layout.activity_main);
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.inflateMenu(R.menu.menu_main);
    }

    private void initListener() {
        toolbar.setOnMenuItemClickListener(this);
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        int id = item.getItemId();
        switch (id) {
            case R.id.action_settings:
                Toast.makeText(this, getResources().getString(R.string.action_settings), Toast.LENGTH_SHORT).show();
                break;
            case R.id.action_about:
                Toast.makeText(this, getResources().getString(R.string.action_about), Toast.LENGTH_SHORT).show();
                break;
            case R.id.action_collect:
                Toast.makeText(this, getResources().getString(R.string.action_collect), Toast.LENGTH_SHORT).show();
                break;
            case R.id.action_like:
                Toast.makeText(this, getResources().getString(R.string.action_like), Toast.LENGTH_SHORT).show();
                break;
            case R.id.action_share:
                Toast.makeText(this, getResources().getString(R.string.action_share), Toast.LENGTH_SHORT).show();
                break;
        }
        return false;
    }
}

是不是很簡(jiǎn)單清晰呢?我們關(guān)于 Toolbar 來(lái)總結(jié)幾點(diǎn)需要注意的地方:

  • 自定義 xmlns:toolbar 否則在 xml 設(shè)置屬性會(huì)失效。
  • 菜單項(xiàng)的條目背景和顏色,均可以在 app:popupTheme="@style/AppTheme.PopupOverlay" style中設(shè)置:
    菜單配置
  • MainActivity 的主題應(yīng)該為 AppTheme.NoActionBar,或者在代碼中動(dòng)態(tài)地調(diào)用 supportRequestWindowFeature(Window.FEATURE_NO_TITLE)
  • 關(guān)于 Toolbar 的屬性還有很多,并且都可定制化(顏色或者大小),如果有需要你甚至可以在上面添加你的自定義 View ,如有需要,請(qǐng)留言或者查閱文檔。

搭建 DrawerLayout

DrawerLayout 是 Google 推出的官方組件,用來(lái)實(shí)現(xiàn)側(cè)滑欄抽屜的效果:

DrawerLayout

相信非常多的人已經(jīng)熟悉 DrawerLayout 的使用了,我們應(yīng)該注意以下兩點(diǎn):

1.DrawerLayout 的第一個(gè)子 View 必須是當(dāng)抽屜沒(méi)有打開(kāi)時(shí)候的默認(rèn)布局。

<?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/drawerlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.melo.blog.wigetdemo.MainActivity">

    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

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

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

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

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

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

</android.support.v4.widget.DrawerLayout>

在我的 Demo 中,CoordinatorLayout 是 DrawerLayout 的第一個(gè)字 View ,來(lái)作為默認(rèn)的沒(méi)有拉開(kāi)抽屜時(shí)候的默認(rèn)布局。假設(shè)我用 DrawerLayout 來(lái)嵌套 content_main 時(shí),content_main 就作為了 DrawerLayout 未拉開(kāi)的默認(rèn)布局,此時(shí)抽屜應(yīng)該是在 Toolbar 之下拉出的。

2.第二點(diǎn)需要注意就是 抽屜的拉出方向,是由 DrawerLayout 本身的頂層布局的 layout_gravity 屬性設(shè)置的,start就是左側(cè)拉出,end就是右側(cè)拉出,這個(gè)布局我起名為 common_drawer ,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/navigation_drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:background="#ffffff"
    android:orientation="vertical">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="256dp"
        android:background="@mipmap/drawer_header">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:layout_margin="@dimen/fab_margin"
            android:text="DrawerHeader"
            android:textColor="@color/author_text_color"
            android:textSize="@dimen/author_text_size" />

    </FrameLayout>

</LinearLayout>

最后我將這個(gè)布局在 activity_main 中 include 引入。
當(dāng)然,我們是比較關(guān)心 DrawerLayout 和 Toolbar 設(shè)置的 navigation 按鈕 icon 是如何建立關(guān)聯(lián)的,其實(shí)很簡(jiǎn)單,在 代碼中調(diào)用這行代碼:

ActionBarDrawerToggle mToggle = new ActionBarDrawerToggle(this,drawerlayout,toolbar, R.string.open,R.string.close);

然后在 onPostCreate 方法中 調(diào)用 mToggle.syncState() 來(lái)同步滑動(dòng)狀態(tài)。
另外想多提一句,NavigationDrawer 是 google 規(guī)范的 抽屜內(nèi)容的布局,不過(guò)定制性比較差,并不建議你項(xiàng)目中使用它。
當(dāng)然有關(guān) DrawerLayout 還有很多屬性可以配置,有其他需要就去查查官方文檔吧~

我準(zhǔn)備再開(kāi)一個(gè)坑,就是爭(zhēng)取慢慢熟悉所有 MD 風(fēng)格的組件,每一個(gè)都能寫(xiě) Demo 來(lái)練練手,喜歡就關(guān)注下好了。項(xiàng)目的 Github 地址如下:

WigetDemo--Melo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,698評(píng)論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,202評(píng)論 3 426
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 177,742評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 63,580評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,297評(píng)論 6 410
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 55,688評(píng)論 1 327
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,693評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,875評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,438評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,183評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,384評(píng)論 1 372
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,931評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,612評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 35,022評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 36,297評(píng)論 1 292
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,093評(píng)論 3 397
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,330評(píng)論 2 377

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,702評(píng)論 25 708
  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線程,因...
    小菜c閱讀 6,489評(píng)論 0 17
  • 本文出自 “阿敏其人” 簡(jiǎn)書(shū)博客,轉(zhuǎn)載或引用請(qǐng)注明出處。 一、Google口中的ToolBar 從Toolbar說(shuō)...
    阿敏其人閱讀 4,226評(píng)論 2 36
  • 雪蝶曼妙舞瓊臺(tái),一剪寒梅次第開(kāi)。 佳麗短裙著厚襖,賢仁長(zhǎng)款暖襟懷。 相思縷縷無(wú)需怨,牽掛絲絲不必猜。 歲月靜好共祈...
    徐淑英柔情婉淑女薔薇閱讀 277評(píng)論 0 1
  • 梁山好漢大家很熟悉,但你們聽(tīng)過(guò)梁山壞漢嗎? 被高俅關(guān)押了的梁山好漢,要戴上一頂紙帽子,上書(shū)“梁山壞漢”,上街巡游,...
    唐風(fēng)遺人閱讀 434評(píng)論 0 0