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

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

1.png

搭建基礎

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">

            <!-- 主界面的內容都在這里寫 -->
        </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標簽引入的,而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="司機通訊錄"/>
        <item
            android:id="@+id/nav_car_detail_list"
            android:icon="@drawable/ic_favorite_black_24dp"
            android:checkable="true"
            android:title="車輛信息"/>
    </group>
</menu>

4.通過以上的步驟,基本上就已經把側滑邊欄的主體已經搭建完畢了,但是這會的應用雖然已經可以運行,但是還是遠遠達不到我們的要求的,比如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>
        <!--按鈕的顏色樣式設置-->
        <item name="drawerArrowStyle">@style/AppTheme.DrawerArrowToggle</item>
    </style>

    <!-- 設置左上角菜單和返回按鈕的顏色樣式-->
    <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>
        <!--按鈕的顏色樣式設置-->
        <item name="drawerArrowStyle">@style/AppTheme.DrawerArrowToggle</item>
    </style>

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


好的,現(xiàn)在主題文件基本上已經設置完畢了,整個應用的風格已經是我們想要的樣子了。

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

2.png

這些操作都需要在Activity中進行,下面是設置的代碼,基本上都有注釋:


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關聯(lián)
        setSupportActionBar(toolbar);
        //設置顯示左上角的返回鍵
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        //給左上角的圖標加上開關屬性,這個是套路,少一個步驟都觸發(fā)不了開關效果。
       mDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.drawer_open,
                R.string.drawer_close);
      //該方法會自動和actionBar關聯(lián), 將開關的圖片顯示在了action上,如果不設置,也可以有抽屜的效果,不過是默認的圖標
        mDrawerToggle.syncState();
        drawerLayout.addDrawerListener(mDrawerToggle);

}

}


6.寫完這個步驟,基本上左邊的側邊欄不管是點擊左上角的圖標呼出還是手勢側滑呼出就都可以實現(xiàn)了,現(xiàn)在要做的就是為側滑邊欄中的菜單項以及Toolbar上最右邊加入一個鈴鐺的圖標并加入點擊事件了,首先先在Toolbar右側加入鈴鐺圖標吧,這里需要現(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的兩個方法進行創(chuàng)建菜單:onPrepareOptionsMenu(Menu menu),onCreateOptionsMenu。
兩種方法的區(qū)別是,前者是每次點擊menu鍵都會重新調用,所以,如果菜單需要更新的話,就用此方法。而后者只是在activity創(chuàng)建的時候執(zhí)行一次。

看到這里我們在結合我們的代碼就知道了,我們創(chuàng)建了一個菜單,菜單中只有一個按鈕,這個按鈕就是我們的鈴鐺圖標。

7.好的,最后一步,給我們的側滑邊欄和菜單按鈕都加上點擊事件吧。
在主Activity中加入如下代碼:

  //為左側的菜單加入點擊效果
        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,"司機通訊錄","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里設置,也可以像ActionBar那樣,通過Activity的onOptionsItemSelected回調方法來處理 */
        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;
            }
        });

具體內容看代碼即可,應該沒什么難度,只是要明白,如果我們選擇處理這個點擊事件就要把該事件返回true,從而攔截該事件。

結語

隨著MaterialDesign越來越廣泛的應用到各個大型或者小型的應用中去,學會搭建一套MD風格的軟件框架就成為一個安卓程序員必須會的知識了,今天我這里只是粗淺的帶領大家搭建一個MD風格的APP,希望朋友們都可以深入的去學習這套框架,做出屬于自己風格的MD應用。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容