今天來講Android如何使用Toolbar並且加入Navigation Drawer,首先Navigation Drawer可以直接在Android Studio(以下簡稱AS)新建專案的時候,選擇 Navigation Drawer Activity範例來建立新專案。建立完成之後,AS會自動幫你產生下列檔案:

res/layout資料夾

  • activity_main.xml
  • fragment_main.xml
  • fragment_navigation_drawer.xml

java/package-name資料夾(package-name是你專案的package名稱)

  • MainActivity.java
  • NavigationDrawerFragment.java

接下來要開始修改這些檔案,加入Toolbar而且把Navigation Drawer改成Material Design,讓我們開始吧~


新增Toolbar Layout檔案

我們從Toolbar開始,先在build.gradle裡面加入

compile 'com.android.support:appcompat-v7:22.2.0'

讓gradle同步完後,建立新的layout檔案叫做toolbar.xml,裡面加入

<android.support.v7.widget.Toolbar
    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="wrap_content"
    android:background="?attr/colorPrimary"
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/Theme.AppCompat.Light.DarkActionBar"
    android:fitsSystemWindows="true"
    />
  • 記得是使用v7的Toolbar而非android.widget.Toolbar!!!
  • android:background="?attr/colorPrimary 這邊是使用@style/colorPrimary來設定背景顏色,這是Android 5.0以後的寫法。
  • android:fitsSystemWindows="true" 這是讓Toolbar可以向上延伸到狀態列,主要是用在Android 4.4可以使用透明的狀態列。

加入Toolbar到主介面

再來activity_main.xml裡面我們要把剛剛建立的toolbar.xml引入,所以用一個RelativeLayoutToolbar用include的方式和主要內容的FrameLayout包起來如下

<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <include
            android:id="@+id/toolbar"
            layout="@layout/toolbar"/>

        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/toolbar"/>
    </RelativeLayout>

    <fragment
        android:id="@+id/navigation_drawer"
        android:name="com.moviebomber.ui.fragment.NavigationDrawerFragment"
        android:layout_width="@dimen/navigation_drawer_width"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        tools:layout="@layout/fragment_navigation_drawer"/>
</android.support.v4.widget.DrawerLayout>

修改style檔案

因為我們要用Toolbar取代Actionbar,所以需要把原本的styles.xml修改如下

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

改成

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/primary</item>
    <item name="colorPrimaryDark">@color/primary_dark</item>
    <item name="colorAccent">@color/accent</item>
    <item name="android:windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
    <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
</style>

<style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
    <item name="spinBars">true</item>
    <item name="color">@android:color/white</item>
</style>
  • colorPrimary, colorPrimaryDak, colorAccent顏色對應關係可以見下圖,這是讓Android 5.0可以抓到對應的顏色。

  • android:windowNoTitle把視窗標題移除, windowActionBar不使用Actionbar。
  • drawerArrowStyle和下面DrawerArrowStyle是做出開啟Navigation Drawer漢堡變箭頭的動畫(如下圖)


在MainActivity.java使用Toolbar

MainActivity.java要加入Toolbar並且把Actionbar指向Toolbar,然後設定Statusbar為透明的。

public class MainActivity extends AppCompatActivity 
    implements NavigationDrawerFragment.NavigationDrawerCallbacks {

    @InjectView(R.id.toolbar)
    Toolbar mToolbar;

    /**
     * Fragment managing the behaviors, interactions and presentation of the navigation drawer.
     */
    private NavigationDrawerFragment mNavigationDrawerFragment;

    /**
     * Used to store the last screen title. For use in {@link #restoreActionBar()}.
     */
    private CharSequence mTitle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Window w = getWindow(); // in Activity's onCreate() for instance

            w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
        setContentView(R.layout.activity_main);
        ButterKnife.inject(this);
        this.setSupportActionBar(this.mToolbar);

        mNavigationDrawerFragment = (NavigationDrawerFragment)
                getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
        mTitle = getTitle();

        // Set up the drawer.

        mNavigationDrawerFragment.setUp(
                R.id.navigation_drawer,
                this.mToolbar,
                (DrawerLayout) findViewById(R.id.drawer_layout));
    }
}
  • 增加了mToolbar的成員,這邊是import android.support.v7.widget.Toolbar;,我們都是使用v7的Toolbar!
  • if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {那一段是把Statusbar設為透明的,讓colorPrimaryDark也可以在Android 4.4顯示出來,讓Toolbar可以延伸到Statusbar。
  • 使用setSupportActionBar()把Toolbar傳入。
  • mNavigationDrawerFragment.setUp(...)這方法要傳入Toolbar,所以下列的NavigationDrawlerFragment.java要改掉API。

NavigationDrawerFragment.java使用Toolbar

NavigationDrawerFragment.java要可以知道Toolbar的狀態,得知是否有按下漢堡,所以改動的地方如下

public void setUp(int fragmentId, Toolbar toolbar, DrawerLayout drawerLayout)  {
    mDrawerToggle = new ActionBarDrawerToggle(
                getActivity(),                    /* host Activity */
                mDrawerLayout,                    /* DrawerLayout object */
                toolbar,
                R.string.navigation_drawer_open,  /* "open drawer" description for accessibility */
                R.string.navigation_drawer_close  /* "close drawer" description for accessibility */
        )
} 
  • 原本setup()API多加了Toolbar當傳入參數。
  • ActionBarDrawerToggle要從v4換成v7的,並且把Toolbar傳入。

完成結果

  • 現在上面是Toolbar,不是Actionbar。

  • 展開功能表

完成收工!!

Comments

comments powered by Disqus