【原創+譯文】官方文檔中聲明的如何建立抽屜導覽列(Navigation Drawer),navigationdrawer
如需轉載請註明出處:http://www.cnblogs.com/ghylzwsb/p/5831759.html建立一個抽屜導覽列
抽屜式導覽列是顯示在螢幕的左邊緣,它是應用程式的主導航選項面板。它大部分時間是處於隱藏狀態的,但是當使用者從螢幕的左邊緣揮動手指時它就會顯示出來,而在應用程式的頂層,使用者觸摸操作欄上的應用程式圖示也可以將其顯示出來。
本課程介紹在可用的API 支援庫下如何?隱藏式瀏覽選單DrawerLayout。
首先我們可以看一下最終的:
1、建立一個抽屜布局檔案(Drawer Layout)
要添加一個抽屜式導航,首先你必須要聲明你的使用者介面的根布局為DrawerLayout對象。在DrawerLayout裡面,添加一個主視圖內容的view對象(當抽屜被隱藏的時候顯示在螢幕上的 視圖)和另外一個包含抽屜導航視圖的view對象。
例如,下面的布局採用了包含兩個子視圖的DrawerLayout:一個是FrameLayout,包含了主要內容(在運行時由填充Fragment),和一個ListView的隱藏式瀏覽選單。
1 <android.support.v4.widget.DrawerLayout 2 xmlns:android="http://schemas.android.com/apk/res/android" 3 android:id="@+id/drawer_layout" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" > 6 7 <!-- 主視圖 --> 8 <FrameLayout 9 android:id="@+id/content_frame"10 android:layout_width="match_parent"11 android:layout_height="match_parent" />12 13 <!-- 抽屜視圖 -->14 <ListView15 android:id="@+id/left_drawer"16 android:layout_width="240dp"17 android:layout_height="match_parent"18 android:layout_gravity="start"19 android:background="#111"20 android:choiceMode="singleChoice"21 android:divider="@android:color/transparent"22 android:dividerHeight="0dp" />23 24 </android.support.v4.widget.DrawerLayout>
這個布局檔案示範了一些比較重要的布局特點,如下:
- 主內容視圖(上面的FrameLayout)必須是DrawerLayout布局對象的第一個子view對象,這是因為xml檔案意味著是z排序(即空間上的上下排序,也就是說抽屜導覽列應該位於住內容視圖的垂直上方)。
- 主內容視圖的view對象的兩個屬性:layout_width、layout_height必須是match_parent的,這是因為當抽屜導覽列被隱藏的時候他便是整個UI。
- 抽屜視圖要指定其寬度的單位為dp,高度與父視圖相匹配。抽屜的寬度應該不超過320dp,這樣使用者可以隨時看到主要內容視圖的一些部分。
- 抽屜視圖(ListView)必須用 android:layout_gravity 屬性來指定他的水平重力方向。為了支援從右至左(RTL)的語言,應該要指定其屬性為"start" ,而不是"left" 。
2、初始化抽屜列表
在你的Activity中,首先要做的事之一就是初始化抽屜導覽列中的清單項目。至於你要如何做取決於你的應用程式中的內容,但是通常情況下抽屜導覽列都是包含了一個ListView,所以列表應該由Adapter來填充(如ArrayAdapter或者SimpleCursorAdapter)。
例如下面將告訴你如何用字串數組初始化抽屜導覽列列表:
public class MainActivity extends Activity { private String[] mPlanetTitles; private DrawerLayout mDrawerLayout; private ListView mDrawerList; ... @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mPlanetTitles = getResources().getStringArray(R.array.planets_array); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerList = (ListView) findViewById(R.id.left_drawer); // Set the adapter for the list view mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, mPlanetTitles)); // Set the list's click listener mDrawerList.setOnItemClickListener(new DrawerItemClickListener()); ... }}
此代碼還調用setOnItemClickListener()來接收抽屜導覽列列表的點擊事件。下一節將展示如何?此介面,以實現當使用者選擇一個項目後更改主內容視圖。
3、處理導航的點擊事件
當使用者選擇在抽屜導覽列裡列表中的項目時,系統調用OnItemClickListener介面中的onItemClick()方法以返回給OnItemClickListener() 。你要在onItemClick()方法中做什麼樣的處理取決於你如何?你的的應用程式結構。在下面的例子中,你將可以實現下面的內容:當點擊抽屜導覽列中清單項目裡的item時,將會在住內容視圖中插入一個不同的Fragment。(FrameLayout的id為 R.id.content_frame)。
private class DrawerItemClickListener implements ListView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { selectItem(position); }}/** Swaps fragments in the main content view */private void selectItem(int position) { // Create a new fragment and specify the planet to show based on position Fragment fragment = new PlanetFragment(); Bundle args = new Bundle(); args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position); fragment.setArguments(args); // Insert the fragment by replacing any existing fragment FragmentManager fragmentManager = getFragmentManager(); fragmentManager.beginTransaction() .replace(R.id.content_frame, fragment) .commit(); // Highlight the selected item, update the title, and close the drawer mDrawerList.setItemChecked(position, true); setTitle(mPlanetTitles[position]); mDrawerLayout.closeDrawer(mDrawerList);}@Overridepublic void setTitle(CharSequence title) { mTitle = title; getActionBar().setTitle(mTitle);}4、監聽開啟以及關閉抽屜導覽列的事件
要監聽抽屜開啟和關閉事件,在你的DrawerLayout中調用setDrawerListener()並傳入一個DrawerLayout.DrawerListener介面 。此介面為抽屜導覽列提供了回掉方法,如onDrawerOpened()和onDrawerClosed()。
然而,除了實現DrawerLayout.DrawerListener介面之外,如果你的Activity包含了ActionBar,你也可以繼承ActionBarDrawerToggle這個類,這是因為ActionBarDrawerToggle類實現DrawerLayout.DrawerListener介面,所以你仍然可以複寫這些方法,但是這對ActionBar表徵圖和抽屜的互動也有一定的協助。
正如在抽屜導航設計指南討論的一樣,當抽屜處於可見狀態時你應該要修改操作欄(ActionBar)的內容,例如你應該要改變標題,並移除與主內容試圖相關的清單項目。下面的代碼示範了如何通過執行個體化ActionBarDrawerToggle類並複寫在DrawerLayout.DrawerListener中的回調方法,以達到這樣的目的:
public class MainActivity extends Activity { private DrawerLayout mDrawerLayout; private ActionBarDrawerToggle mDrawerToggle; private CharSequence mDrawerTitle; private CharSequence mTitle; ... @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... mTitle = mDrawerTitle = getTitle(); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) { /** Called when a drawer has settled in a completely closed state. */ public void onDrawerClosed(View view) { super.onDrawerClosed(view); getActionBar().setTitle(mTitle); invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu() } /** Called when a drawer has settled in a completely open state. */ public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); getActionBar().setTitle(mDrawerTitle); invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu() } }; // Set the drawer toggle as the DrawerListener mDrawerLayout.setDrawerListener(mDrawerToggle); } /* Called whenever we call invalidateOptionsMenu() */ @Override public boolean onPrepareOptionsMenu(Menu menu) { // If the nav drawer is open, hide action items related to the content view boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList); menu.findItem(R.id.action_websearch).setVisible(!drawerOpen); return super.onPrepareOptionsMenu(menu); }}
下一節將介紹ActionBarDrawerToggle建構函式的參數,並設定它來處理與操作欄表徵圖互動所需的其他步驟。
5、如何通過應用程式圖示開啟或關閉抽屜導覽列
使用者可以通過來自或朝向螢幕的左邊緣輕掃的手勢來開啟與關閉抽屜式導覽列,但如果你正在使用操作欄(ActionBar) ,你也應該允許使用者通過觸摸應用程式圖示的方式開啟或者關閉抽屜導覽列。而應用程式圖示也應用一個特殊的表徵圖註明抽屜的存在。你也可以通過實現上一節講到的ActionBarDrawerToggle來實現這些行為。
為了使ActionBarDrawerToggle發揮作用,你將需要建立它的一個執行個體與它的構造方法,這需要下列參數:
- 持有該抽屜的Activity
- 一個DrawerLayout
- 用於作為抽屜指標的繪製資源(drawable resource),這裡會提供一個android官方提供的表徵圖包:Android_Design_Icons_20130926.zip。
- 用來形容“開啟抽屜”這一操作的字串資源
- 用來形容“關閉抽屜”這一操作的字串資源
最後,不管你是否已經建立了ActionBarDrawerToggle的子類作為抽屜的監聽器,你還是需要在整個Activity的生命週期中的幾個地方調用ActionBarDrawerToggle:
public class MainActivity extends Activity { private DrawerLayout mDrawerLayout; private ActionBarDrawerToggle mDrawerToggle; ... public void onCreate(Bundle savedInstanceState) { ... mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerToggle = new ActionBarDrawerToggle( this, /* host Activity */ mDrawerLayout, /* DrawerLayout object */ R.drawable.ic_drawer, /* nav drawer icon to replace 'Up' caret */ R.string.drawer_open, /* "open drawer" description */ R.string.drawer_close /* "close drawer" description */ ) { /** Called when a drawer has settled in a completely closed state. */ public void onDrawerClosed(View view) { super.onDrawerClosed(view); getActionBar().setTitle(mTitle); } /** Called when a drawer has settled in a completely open state. */ public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); getActionBar().setTitle(mDrawerTitle); } }; // Set the drawer toggle as the DrawerListener mDrawerLayout.setDrawerListener(mDrawerToggle); getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setHomeButtonEnabled(true); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // Sync the toggle state after onRestoreInstanceState has occurred. mDrawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mDrawerToggle.onConfigurationChanged(newConfig); } @Override public boolean onOptionsItemSelected(MenuItem item) { // Pass the event to ActionBarDrawerToggle, if it returns // true, then it has handled the app icon touch event if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } // Handle your other action bar items... return super.onOptionsItemSelected(item); } ...}
教程的最後,我提供了項目的:DrawerLayout_sample.rar,希望這個教程能夠幫到你。
BOB
2016-09-03