Navigation Drawer介绍
在2013 google IO當(dāng)天,Android團(tuán)的更新了Support庫(kù),新版本(V13)的Support庫(kù)中新加入了幾個(gè)比較重要的功能。
- 添加?DrawerLayout?控件,支持創(chuàng)建 ?Navigation Drawer模式。可以設(shè)置從左邊劃出菜單或者右邊,也可以左右菜單同時(shí)存在。
- 添加?SlidingPaneLayout?控件來(lái)支持各種屏幕上的摘要、詳情界面模式。比如 Gmail郵件列表和單個(gè)郵件詳情界面。當(dāng)在手機(jī)上顯示的時(shí)候,郵件列表和詳情界面分別為兩個(gè)界面;當(dāng)在平板上顯示的時(shí)候,則為一個(gè)界面。
- 添加?ActionBarDrawerToggle?工具類,方便把?DrawerLayout?和?ActionBar?功能結(jié)合起來(lái)。
創(chuàng)建Drawer Layout
在需要抽屜菜單的界面,用DrawerLayout?作為界面根控件。在DrawerLayout里面第一個(gè)View為當(dāng)前界面主內(nèi)容;第二個(gè)和第三個(gè)View為抽屜菜單內(nèi)容。如果當(dāng)前界面只需要一個(gè)抽屜菜單,則第三個(gè)View可以省略。
下面的例子中DrawerLayout里面包含兩個(gè)View,第一個(gè)FrameLayout中是當(dāng)前界面主要內(nèi)容顯示區(qū)域;第二個(gè)ListView為抽屜菜單內(nèi)容。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <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"> ????<!-- The main content view --> ????<FrameLayout ????????android:id="@+id/content_frame" ????????android:layout_width="match_parent" ????????android:layout_height="match_parent" /> ????<!-- The navigation drawer --> ????<ListView android:id="@+id/left_drawer" ????????android:layout_width="240dp" ????????android:layout_height="match_parent" ????????android:layout_gravity="start" ????????android:choiceMode="singleChoice" ????????android:divider="@android:color/transparent" ????????android:dividerHeight="0dp" ????????android:background="#111"/> </android.support.v4.widget.DrawerLayout> |
上面的代碼中有如下幾點(diǎn)需要注意:
- 顯示界面主要內(nèi)容的View (上面的?FrameLayout?)?必須為DrawerLayout的第一個(gè)子View,?原因在于 XML 布局文件中的View順序?yàn)锳ndroid系統(tǒng)中的 z-ordering順序,而抽屜必須出現(xiàn)在內(nèi)容之上。
- 顯示界面內(nèi)容的View寬度和高度設(shè)置為和父View一樣,原因在于當(dāng)抽屜菜單不可見(jiàn)的時(shí)候,界面內(nèi)容代表整個(gè)界面UI。
- 抽屜菜單 (上面的?ListView)?必須使用android:layout_gravity屬性設(shè)置水平的 gravity值?.如果要支持 right-to-left (RTL,從右向左閱讀)語(yǔ)言 用?"start"?代替?"left"?(當(dāng)在 RTL語(yǔ)言運(yùn)行時(shí)候,菜單出現(xiàn)在右側(cè))。
- 抽屜菜單的寬度為?dp?單位而高度和父View一樣。抽屜菜單的寬度應(yīng)該不超過(guò)320dp,這樣用戶可以在菜單打開(kāi)的時(shí)候看到部分內(nèi)容界面。
初始化抽屜菜單
在您的Activity中需要先初始化抽屜菜單內(nèi)容,根據(jù)您的應(yīng)用需要抽屜菜單的內(nèi)容可能不是ListView。
在上面的示例中,我們需要給菜單的ListView設(shè)置一個(gè)Adapter來(lái)提供數(shù)據(jù)。如下所示:
幫助| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | public class MainActivity extends Activity { ????private String[] mPlanetTitles; ????private ListView mDrawerList; ????... ????@Override ????public void onCreate(Bundle savedInstanceState) { ????????super.onCreate(savedInstanceState); ????????setContentView(R.layout.activity_main); ????????mPlanetTitles = getResources().getStringArray(R.array.planets_array); ????????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()); ????????... ????} } |
上面的代碼調(diào)用了?setOnItemClickListener()?函數(shù)來(lái)接受菜單條目點(diǎn)擊事件。下面會(huì)介紹如何更加點(diǎn)擊菜單來(lái)顯示主界面內(nèi)容。
處理菜單點(diǎn)擊事件
當(dāng)用戶選擇菜單List中的條目時(shí),系統(tǒng)會(huì)調(diào)用 ?OnItemClickListener的?onItemClick()函數(shù)。
根據(jù)您的應(yīng)用需要onItemClick函數(shù)的實(shí)現(xiàn)方式可能不同。下面的示例中,選擇菜單條目會(huì)在程序主界面中插入不同的?Fragment?。
幫助| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 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 ????mDrawer.setItemChecked(position, true); ????setTitle(mPlanetTitles[position]); ????mDrawerLayout.closeDrawer(mDrawer); } @Override public void setTitle(CharSequence title) { ????mTitle = title; ????getActionBar().setTitle(mTitle); } |
監(jiān)聽(tīng)菜單打開(kāi)關(guān)閉事件
如果需要監(jiān)聽(tīng)菜單打開(kāi)關(guān)閉事件,則需要調(diào)用?DrawerLayout類的?setDrawerListener()?函數(shù),參數(shù)為?DrawerLayout.DrawerListener接口的實(shí)現(xiàn)。該接口提供了菜單打開(kāi)關(guān)閉等事件的回調(diào)函數(shù),例如?onDrawerOpened()?和onDrawerClosed().
如果您的Activity使用了?action bar,則您可以使用Support庫(kù)提供的?ActionBarDrawerToggle?類,該類實(shí)現(xiàn)了?DrawerLayout.DrawerListener接口,并且您還可以根據(jù)需要重寫(xiě)相關(guān)的函數(shù)。該類實(shí)現(xiàn)了菜單和Action bar相關(guān)的操作。
根據(jù)在?Navigation Drawer?設(shè)計(jì)指南中的介紹,當(dāng)菜單顯示的時(shí)候您應(yīng)該根據(jù)情況隱藏ActionBar上的功能菜單并且修改ActionBar的標(biāo)題。下面的代碼演示了如何重寫(xiě)?ActionBarDrawerToggle?類的相關(guān)函數(shù)來(lái)實(shí)現(xiàn)該功能。
幫助| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | 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) { ????????????????getActionBar().setTitle(mTitle); ????????????????invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu() ????????????} ????????????/** Called when a drawer has settled in a completely open state. */ ????????????public void onDrawerOpened(View 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); ????} } |
最后來(lái)介紹下??ActionBarDrawerToggle?類的功能。
應(yīng)用圖標(biāo)指示抽屜開(kāi)關(guān)
用戶可以從屏幕邊緣滑動(dòng)來(lái)打開(kāi)抽屜菜單,如果您使用了?action bar,應(yīng)該讓用戶通過(guò)點(diǎn)擊應(yīng)用圖標(biāo)也可以打開(kāi)抽屜菜單。并且應(yīng)用圖標(biāo)也應(yīng)該使用一個(gè)特殊的圖標(biāo)來(lái)指示抽屜菜單。您可以使用?ActionBarDrawerToggle?類來(lái)實(shí)現(xiàn)這些功能。
要使用?ActionBarDrawerToggle?,先通過(guò)其構(gòu)造函數(shù)來(lái)創(chuàng)建該對(duì)象,構(gòu)造函數(shù)需要如下參數(shù):
- 顯示抽屜的?Activity?對(duì)象
- ?DrawerLayout?對(duì)象
- 一個(gè)用來(lái)指示抽屜的 drawable資源
- 一個(gè)用來(lái)描述打開(kāi)抽屜的文本 (用于支持可訪問(wèn)性)。
- 一個(gè)用來(lái)描述關(guān)閉抽屜的文本(用于支持可訪問(wèn)性).
無(wú)論你是否繼承?ActionBarDrawerToggle?來(lái)實(shí)現(xiàn)抽屜監(jiān)聽(tīng)器,您都需要在Activity的生命周期函數(shù)中調(diào)用ActionBarDrawerToggle?的一些函數(shù)。
如下所示:
幫助| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | 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, 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) { ????????????????getActionBar().setTitle(mTitle); ????????????} ????????????/** Called when a drawer has settled in a completely open state. */ ????????????public void onDrawerOpened(View 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. ????????<span style="color: #ff0000;">mDrawerToggle.syncState();</span> ????} ????@Override ????public void onConfigurationChanged(Configuration newConfig) { ????????super.onConfigurationChanged(newConfig); ????????<span style="color: #ff0000;">mDrawerToggle.onConfigurationChanged(newConfig);</span> ????} ????@Override ????public boolean onOptionsItemSelected(MenuItem item) { ????????// Pass the event to ActionBarDrawerToggle, if it returns ????????// true, then it has handled the app icon touch event ????????<span style="color: #ff0000;">if (mDrawerToggle.onOptionsItemSelected(item)) {</span> <span style="color: #ff0000;"> return true;</span> <span style="color: #ff0000;"> }</span> ????????// Handle your other action bar items... ????????return super.onOptionsItemSelected(item); ????} ????... } |
猛擊我下載示例項(xiàng)目代碼。
?本文出自 云在千峰,轉(zhuǎn)載時(shí)請(qǐng)注明出處及相應(yīng)鏈接。
?本文永久鏈接: http://blog.chengyunfeng.com/?p=493
轉(zhuǎn)載于:https://www.cnblogs.com/krislight1105/p/3748369.html
總結(jié)
以上是生活随笔為你收集整理的Navigation Drawer介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 概念:弱监督学习
- 下一篇: WHU 1470 Join in tas