使用DrawerLayout和NavigationView以及Toolbar創(chuàng)建一個MD風(fēng)格的應(yīng)用框架

--
新項(xiàng)目開發(fā)在即刘离,通過之前的原型設(shè)計垢揩,打算做一個可以實(shí)現(xiàn)側(cè)滑邊欄的應(yīng)用因谎,鑒于谷歌對MaterialDesign的大力推廣闹获,以及官方的一些應(yīng)用的設(shè)計方式,所以打算新的應(yīng)用就使用DrawerLayout+NavigationView+Toolbar來實(shí)現(xiàn)了河哑。
先看效果圖:

1.png

搭建基礎(chǔ)

1.先引入依賴的庫:

compile 'com.android.support:design:23.4.0'

2.然后把主布局文件寫成這樣:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    <include layout="@layout/nav_toolbar"/>
<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:id="@+id/main"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <!-- 主界面的內(nèi)容都在這里寫 -->
        </LinearLayout>
    </FrameLayout>
    <android.support.design.widget.NavigationView
        android:id="@+id/navigation"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/drawer_menu"/>
</android.support.v4.widget.DrawerLayout>
</LinearLayout>

3.在主布局文件中避诽,我們注意到了,Toolbar是用include標(biāo)簽引入的璃谨,而NavigationView中也引入了兩個布局沙庐,一個是nav_header,另一個是activity_main_drawer,這個布局文件是一個menu的布局佳吞,要放在res/menu下哦拱雏,這兩個就是NaigationView的主要組成部分了。
現(xiàn)在讓我們看看這三個布局文件的寫法:

toolbar:

<?xml version="1.0" encoding="utf-8"?>
<app:android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/app_main_color"
android:minHeight="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />

nav_hear:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="192dp"
    android:background="@drawable/nav_header_bg"
    android:orientation="vertical"
    android:padding="@dimen/spacing_normal"
    android:theme="@style/ThemeOverlay.AppCompat.Dark">


    <TextView
        android:id="@+id/id_link"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="@dimen/spacing_normal"
        android:layout_marginTop="@dimen/spacing_tiny"
        android:text="管理部"/>

    <TextView
        android:id="@+id/id_username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@id/id_link"
        android:text="Admin"/>

    <ImageView
        android:layout_width="72dp"
        android:layout_height="72dp"
        android:layout_above="@id/id_username"
        android:layout_marginBottom="@dimen/spacing_normal"
        android:src="@drawable/ic_avatar"/>


</RelativeLayout>

activity_main_drawer:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group >
        <item
        android:id="@+id/nav_driver_contact"
        android:icon="@drawable/ic_favorite_black_24dp"
        android:checkable="true"
        android:title="司機(jī)通訊錄"/>
        <item
            android:id="@+id/nav_car_detail_list"
            android:icon="@drawable/ic_favorite_black_24dp"
            android:checkable="true"
            android:title="車輛信息"/>
    </group>
</menu>

4.通過以上的步驟底扳,基本上就已經(jīng)把側(cè)滑邊欄的主體已經(jīng)搭建完畢了铸抑,但是這會的應(yīng)用雖然已經(jīng)可以運(yùn)行,但是還是遠(yuǎn)遠(yuǎn)達(dá)不到我們的要求的衷模,比如toolbar空空如也啊鹊汛,比如toolbar和statusbar的顏色不是我們想要的啊等等,現(xiàn)在我們就來一步步的完成剩下的工作吧阱冶。
第一步刁憋,先完善主題文件
styles.xml

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:windowIsTranslucent">true</item>
        <!-- toolbar(actionbar)顏色 -->
        <item name="colorPrimary">@color/app_main_color</item>
        <!-- 狀態(tài)欄顏色 -->
        <item name="colorPrimaryDark">@color/app_main_color</item>
        <!-- 窗口的背景顏色 -->
        <item name="android:windowBackground">@android:color/white</item>
        <!--文字的顏色-->
        <item name="android:textColorPrimary">@color/black_white</item>
        <!--按鈕的顏色樣式設(shè)置-->
        <item name="drawerArrowStyle">@style/AppTheme.DrawerArrowToggle</item>
    </style>

    <!-- 設(shè)置左上角菜單和返回按鈕的顏色樣式-->
    <style name="AppTheme.DrawerArrowToggle" parent="Base.Widget.AppCompat.DrawerArrowToggle">
        <item name="color">@android:color/white</item>
    </style>
</resources>


文件中有一些自定義的顏色,用到了colors.xml


<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:windowIsTranslucent">true</item>
        <!-- toolbar(actionbar)顏色 -->
        <item name="colorPrimary">@color/app_main_color</item>
        <!-- 狀態(tài)欄顏色 -->
        <item name="colorPrimaryDark">@color/app_main_color</item>
        <!-- 窗口的背景顏色 -->
        <item name="android:windowBackground">@android:color/white</item>
        <!--文字的顏色-->
        <item name="android:textColorPrimary">@color/black_white</item>
        <!--按鈕的顏色樣式設(shè)置-->
        <item name="drawerArrowStyle">@style/AppTheme.DrawerArrowToggle</item>
    </style>

    <!-- 設(shè)置左上角菜單和返回按鈕的顏色樣式-->
    <style name="AppTheme.DrawerArrowToggle" parent="Base.Widget.AppCompat.DrawerArrowToggle">
        <item name="color">@android:color/white</item>
    </style>
</resources>


好的木蹬,現(xiàn)在主題文件基本上已經(jīng)設(shè)置完畢了至耻,整個應(yīng)用的風(fēng)格已經(jīng)是我們想要的樣子了。

5.現(xiàn)在還差一個就是在toolbar上加一個菜單按鈕,讓我們的應(yīng)用不僅可以通過手勢側(cè)滑呼出菜單欄也可以點(diǎn)擊左上角的menu圖標(biāo)顯示菜單欄尘颓,如圖:

2.png

這些操作都需要在Activity中進(jìn)行走触,下面是設(shè)置的代碼,基本上都有注釋:


import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.LinearLayout;

import com.dhcc.obd.R;
import com.dhcc.obdcore_library.Util.ToastUtil;

import butterknife.BindView;
import butterknife.ButterKnife;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();
    @BindView(R.id.main)
    LinearLayout main;
    @BindView(R.id.navigation)
    NavigationView navigation;
    @BindView(R.id.drawer_layout)
    DrawerLayout drawerLayout;
    @BindView(R.id.toolbar)
    Toolbar toolbar;
    ActionBarDrawerToggle mDrawerToggle;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        toolbar.setTitle("東華車管");
        toolbar.setTitleTextColor(ContextCompat.getColor(this,R.color.white));
        //將toolbar與ActionBar關(guān)聯(lián)
        setSupportActionBar(toolbar);
        //設(shè)置顯示左上角的返回鍵
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        //給左上角的圖標(biāo)加上開關(guān)屬性泥耀,這個是套路饺汹,少一個步驟都觸發(fā)不了開關(guān)效果。
       mDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.drawer_open,
                R.string.drawer_close);
      //該方法會自動和actionBar關(guān)聯(lián), 將開關(guān)的圖片顯示在了action上痰催,如果不設(shè)置兜辞,也可以有抽屜的效果,不過是默認(rèn)的圖標(biāo)
        mDrawerToggle.syncState();
        drawerLayout.addDrawerListener(mDrawerToggle);

}

}


6.寫完這個步驟夸溶,基本上左邊的側(cè)邊欄不管是點(diǎn)擊左上角的圖標(biāo)呼出還是手勢側(cè)滑呼出就都可以實(shí)現(xiàn)了逸吵,現(xiàn)在要做的就是為側(cè)滑邊欄中的菜單項(xiàng)以及Toolbar上最右邊加入一個鈴鐺的圖標(biāo)并加入點(diǎn)擊事件了,首先先在Toolbar右側(cè)加入鈴鐺圖標(biāo)吧缝裁,這里需要現(xiàn)在res/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=".MainActivity" >
    <item
        android:id="@+id/tool_car_alarm"
        android:icon="@drawable/ic_notifications_white_24dp"
        android:orderInCategory="90"
        android:title="車輛報警"
        app:showAsAction="ifRoom" />
</menu>

之后在主Activity中加入如下代碼:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }

附加知識:

android中可以重寫activity的兩個方法進(jìn)行創(chuàng)建菜單:onPrepareOptionsMenu(Menu menu)扫皱,onCreateOptionsMenu。
兩種方法的區(qū)別是捷绑,前者是每次點(diǎn)擊menu鍵都會重新調(diào)用韩脑,所以,如果菜單需要更新的話粹污,就用此方法段多。而后者只是在activity創(chuàng)建的時候執(zhí)行一次。

看到這里我們在結(jié)合我們的代碼就知道了壮吩,我們創(chuàng)建了一個菜單进苍,菜單中只有一個按鈕,這個按鈕就是我們的鈴鐺圖標(biāo)鸭叙。

7.好的觉啊,最后一步,給我們的側(cè)滑邊欄和菜單按鈕都加上點(diǎn)擊事件吧沈贝。
在主Activity中加入如下代碼:

  //為左側(cè)的菜單加入點(diǎn)擊效果
        navigation.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            private MenuItem mPreMenuItem;
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {

                switch (menuItem.getItemId()){
                    case R.id.nav_driver_contact:
                        // do something
                        ToastUtil.RightImageToast(MainActivity.this,"司機(jī)通訊錄","short");
                        break;
                    case R.id.nav_car_detail_list:
                        // do something
                        ToastUtil.RightImageToast(MainActivity.this,"車輛信息","short");
                        break;
                }

                if (mPreMenuItem != null) mPreMenuItem.setChecked(false);
                menuItem.setChecked(true);
                drawerLayout.closeDrawers();
                mPreMenuItem = menuItem;
                return true;
            }
        });

        /* 菜單的監(jiān)聽可以在toolbar里設(shè)置杠人,也可以像ActionBar那樣,通過Activity的onOptionsItemSelected回調(diào)方法來處理 */
        toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.tool_car_alarm:
                        ToastUtil.RightImageToast(MainActivity.this,"車輛報警","short");
                        break;
                    default:
                        break;
                }
                return true;
            }
        });

具體內(nèi)容看代碼即可缀程,應(yīng)該沒什么難度搜吧,只是要明白,如果我們選擇處理這個點(diǎn)擊事件就要把該事件返回true,從而攔截該事件杨凑。

結(jié)語

隨著MaterialDesign越來越廣泛的應(yīng)用到各個大型或者小型的應(yīng)用中去滤奈,學(xué)會搭建一套MD風(fēng)格的軟件框架就成為一個安卓程序員必須會的知識了,今天我這里只是粗淺的帶領(lǐng)大家搭建一個MD風(fēng)格的APP撩满,希望朋友們都可以深入的去學(xué)習(xí)這套框架蜒程,做出屬于自己風(fēng)格的MD應(yīng)用绅你。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市昭躺,隨后出現(xiàn)的幾起案子忌锯,更是在濱河造成了極大的恐慌,老刑警劉巖领炫,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件偶垮,死亡現(xiàn)場離奇詭異,居然都是意外死亡帝洪,警方通過查閱死者的電腦和手機(jī)似舵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來葱峡,“玉大人砚哗,你說我怎么就攤上這事∨檗龋” “怎么了蛛芥?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長军援。 經(jīng)常有香客問我仅淑,道長,這世上最難降的妖魔是什么胸哥? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任漓糙,我火速辦了婚禮,結(jié)果婚禮上烘嘱,老公的妹妹穿的比我還像新娘。我一直安慰自己蝗蛙,他們只是感情好蝇庭,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著捡硅,像睡著了一般哮内。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上壮韭,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天北发,我揣著相機(jī)與錄音,去河邊找鬼喷屋。 笑死琳拨,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的屯曹。 我是一名探鬼主播狱庇,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼惊畏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了密任?” 一聲冷哼從身側(cè)響起颜启,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎浪讳,沒想到半個月后缰盏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡淹遵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年口猜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片合呐。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡暮的,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出淌实,到底是詐尸還是另有隱情冻辩,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布拆祈,位于F島的核電站恨闪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏放坏。R本人自食惡果不足惜咙咽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望淤年。 院中可真熱鬧钧敞,春花似錦、人聲如沸麸粮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽弄诲。三九已至愚战,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間齐遵,已是汗流浹背寂玲。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留梗摇,地道東北人拓哟。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像留美,于是被迫代替她去往敵國和親彰檬。 傳聞我的和親對象是個殘疾皇子伸刃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

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