天天看點

Android的導航抽屜---Navigation Drawer

     2013 Google I/O大會已經過去好幾天了,我似乎有點跟不上節奏,也沒抽出時間去仔細看一遍,似乎沒有想象中那麼轟動,,很多同學可能認為,谷歌即使不拿出Android 5.0酸橙派,好歹也會弄個Android 4.3出來裝裝樣子,可是什麼都沒有,也沒有新手機Nexus 5的任何消息,不免有點兒失望。算了,不管幹貨多與少,對于Android開發者來說,先來看看推出的新功能Navigation Drawer吧。

官網詳細說明:http://developer.android.com/design/patterns/navigation-drawer.html

本來想用我蹩腳的E文把官方文檔根據自己的翻譯一下,可查閱資料過程中發現大牛已經寫的很好很詳細了,特拿過來跟大家分享一下,下面引用了雲在千峰的博文中的一些内容,

下面來介紹下如何使用

 DrawerLayout

 控件來實作抽屜菜單

建立Drawer Layout

在需要抽屜菜單的界面,用

DrawerLayout

 作為界面根控件。在DrawerLayout裡面第一個View為目前界面主内容;第二個和第三個View為抽屜菜單内容。如果目前界面隻需要一個抽屜菜單,則第三個View可以省略。

下面的例子中DrawerLayout裡面包含兩個View,第一個FrameLayout中是目前界面主要内容顯示區域;第二個ListView為抽屜菜單内容。

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <ListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:background="#111"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp" />

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

上面的代碼中有如下幾點需要注意:

  • 顯示界面主要内容的View (上面的 

    FrameLayout

     ) 必須為DrawerLayout的第一個子View, 原因在于 XML 布局檔案中的View順序為Android系統中的 z-ordering順序,而抽屜必須出現在内容之上。
  • 顯示界面内容的View寬度和高度設定為和父View一樣,原因在于當抽屜菜單不可見的時候,界面内容代表整個界面UI。
  • 抽屜菜單 (上面的 

    ListView

    ) 必須使用android:layout_gravity屬性設定水準的 gravity值 .如果要支援 right-to-left (RTL,從右向左閱讀)語言 用 

    "start"

     代替 

    "left"

     (當在 RTL語言運作時候,菜單出現在右側)。
  • 抽屜菜單的寬度為 

    dp

     機關而高度和父View一樣。抽屜菜單的寬度應該不超過320dp,這樣使用者可以在菜單打開的時候看到部分内容界面。

初始化抽屜菜單

在您的Activity中需要先初始化抽屜菜單内容,根據您的應用需要抽屜菜單的内容可能不是ListView。官方示例中普通listView加載固定資料的過程就不多說了,和平時一樣,沒有幹貨。

監聽菜單打開關閉事件

如果需要監聽菜單打開關閉事件,則需要調用 

DrawerLayout類的

setDrawerListener()

 函數,參數為 

DrawerLayout.DrawerListener接口的實作。

該接口提供了菜單打開關閉等事件的回調函數,例如 

onDrawerOpened()

 和

onDrawerClosed()

.

如果您的Activity使用了 action bar,則您可以使用Support庫提供的 

ActionBarDrawerToggle

 類,該類實作了 

DrawerLayout.DrawerListener接口,并且您還可以根據需要重寫相關的函數。該類實作了菜單和Action bar相關的操作。

根據在 Navigation Drawer 設計指南中的介紹,當菜單顯示的時候您應該根據情況隐藏ActionBar上的功能菜單并且修改ActionBar的标題。

應用圖示訓示抽屜開關

使用者可以從螢幕邊緣滑動來打開抽屜菜單,如果您使用了 action bar,應該讓使用者通過點選應用圖示也可以打開抽屜菜單。并且應用圖示也應該使用一個特殊的圖示來訓示抽屜菜單。您可以使用 

ActionBarDrawerToggle

 類來實作這些功能。

要使用 

ActionBarDrawerToggle

 ,先通過其構造函數來建立該對象,構造函數需要如下參數:

  • 顯示抽屜的 

    Activity

     對象
  • DrawerLayout 對象

  • 一個用來訓示抽屜的 drawable資源
  • 一個用來描述打開抽屜的文本 (用于支援可通路性)。
  • 一個用來描述關閉抽屜的文本(用于支援可通路性).

無論你是否繼承 

ActionBarDrawerToggle

 來實作抽屜監聽器,您都需要在Activity的生命周期函數中調用

ActionBarDrawerToggle

 的一些函數。

如下所示:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTitle = mDrawerTitle = getTitle();
        mPlanetTitles = getResources().getStringArray(R.array.planets_array);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.left_drawer);

        //設定拉出導航菜單時陰影,官方示例不明顯,可把圖檔背景修改一下
        mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
        mDrawerList.setAdapter(new ArrayAdapter<String>(this,
                R.layout.drawer_list_item, mPlanetTitles));
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

        //ActionBar操作模式開啟
        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        //初始化 ActionBarDrawerToggle
        mDrawerToggle = new ActionBarDrawerToggle(
                this,                  /* host Activity */
                mDrawerLayout,         /* DrawerLayout object */
                R.drawable.ic_drawer,  /* nav drawer image to replace 'Up' caret */
                R.string.drawer_open,  /* "open drawer" description for accessibility */
                R.string.drawer_close  /* "close drawer" description for accessibility */
                ) {
            public void onDrawerClosed(View view) {
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }

            public void onDrawerOpened(View drawerView) {
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }
        };
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        if (savedInstanceState == null) {
            selectItem(0);
        }
    }
           

( 官方示例下載下傳)

ps:原文有幾點不太明白,希望知道的朋友能指點一下: 1. 一個用來描述打開抽屜的文本 (用于支援可通路性)。  2.當在 RTL語言運作時候,菜單出現在右側    這兩點應該如何了解? 

盡管google推出了新的控件,但感覺和 jfeinstein10的開源控件SlidingMenu以及SimonVT的MenuDrawer還是有很大不同之處,雖然Navigation Drawer寫法及風格都簡單雅緻,但對于最求動态效果的使用者群來說可能後者更有吸引力,當然,仁者見仁智者見智,以上純屬個人觀點,僅供參考。