Navigation Drawer介绍
在2013 google IO當天,Android團的更新了Support庫,新版本(V13)的Support庫中新加入了幾個比較重要的功能。
- 添加?DrawerLayout?控件,支持創(chuàng)建 ?Navigation Drawer模式。可以設(shè)置從左邊劃出菜單或者右邊,也可以左右菜單同時存在。
- 添加?SlidingPaneLayout?控件來支持各種屏幕上的摘要、詳情界面模式。比如 Gmail郵件列表和單個郵件詳情界面。當在手機上顯示的時候,郵件列表和詳情界面分別為兩個界面;當在平板上顯示的時候,則為一個界面。
- 添加?ActionBarDrawerToggle?工具類,方便把?DrawerLayout?和?ActionBar?功能結(jié)合起來。
創(chuàng)建Drawer Layout
在需要抽屜菜單的界面,用DrawerLayout?作為界面根控件。在DrawerLayout里面第一個View為當前界面主內(nèi)容;第二個和第三個View為抽屜菜單內(nèi)容。如果當前界面只需要一個抽屜菜單,則第三個View可以省略。
下面的例子中DrawerLayout里面包含兩個View,第一個FrameLayout中是當前界面主要內(nèi)容顯示區(qū)域;第二個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> |
上面的代碼中有如下幾點需要注意:
- 顯示界面主要內(nèi)容的View (上面的?FrameLayout?)?必須為DrawerLayout的第一個子View,?原因在于 XML 布局文件中的View順序為Android系統(tǒng)中的 z-ordering順序,而抽屜必須出現(xiàn)在內(nèi)容之上。
- 顯示界面內(nèi)容的View寬度和高度設(shè)置為和父View一樣,原因在于當抽屜菜單不可見的時候,界面內(nèi)容代表整個界面UI。
- 抽屜菜單 (上面的?ListView)?必須使用android:layout_gravity屬性設(shè)置水平的 gravity值?.如果要支持 right-to-left (RTL,從右向左閱讀)語言 用?"start"?代替?"left"?(當在 RTL語言運行時候,菜單出現(xiàn)在右側(cè))。
- 抽屜菜單的寬度為?dp?單位而高度和父View一樣。抽屜菜單的寬度應(yīng)該不超過320dp,這樣用戶可以在菜單打開的時候看到部分內(nèi)容界面。
初始化抽屜菜單
在您的Activity中需要先初始化抽屜菜單內(nèi)容,根據(jù)您的應(yīng)用需要抽屜菜單的內(nèi)容可能不是ListView。
在上面的示例中,我們需要給菜單的ListView設(shè)置一個Adapter來提供數(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ù)來接受菜單條目點擊事件。下面會介紹如何更加點擊菜單來顯示主界面內(nèi)容。
處理菜單點擊事件
當用戶選擇菜單List中的條目時,系統(tǒng)會調(diào)用 ?OnItemClickListener的?onItemClick()函數(shù)。
根據(jù)您的應(yīng)用需要onItemClick函數(shù)的實現(xiàn)方式可能不同。下面的示例中,選擇菜單條目會在程序主界面中插入不同的?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)聽菜單打開關(guān)閉事件
如果需要監(jiān)聽菜單打開關(guān)閉事件,則需要調(diào)用?DrawerLayout類的?setDrawerListener()?函數(shù),參數(shù)為?DrawerLayout.DrawerListener接口的實現(xiàn)。該接口提供了菜單打開關(guān)閉等事件的回調(diào)函數(shù),例如?onDrawerOpened()?和onDrawerClosed().
如果您的Activity使用了?action bar,則您可以使用Support庫提供的?ActionBarDrawerToggle?類,該類實現(xiàn)了?DrawerLayout.DrawerListener接口,并且您還可以根據(jù)需要重寫相關(guān)的函數(shù)。該類實現(xiàn)了菜單和Action bar相關(guān)的操作。
根據(jù)在?Navigation Drawer?設(shè)計指南中的介紹,當菜單顯示的時候您應(yīng)該根據(jù)情況隱藏ActionBar上的功能菜單并且修改ActionBar的標題。下面的代碼演示了如何重寫?ActionBarDrawerToggle?類的相關(guān)函數(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); ????} } |
最后來介紹下??ActionBarDrawerToggle?類的功能。
應(yīng)用圖標指示抽屜開關(guān)
用戶可以從屏幕邊緣滑動來打開抽屜菜單,如果您使用了?action bar,應(yīng)該讓用戶通過點擊應(yīng)用圖標也可以打開抽屜菜單。并且應(yīng)用圖標也應(yīng)該使用一個特殊的圖標來指示抽屜菜單。您可以使用?ActionBarDrawerToggle?類來實現(xiàn)這些功能。
要使用?ActionBarDrawerToggle?,先通過其構(gòu)造函數(shù)來創(chuàng)建該對象,構(gòu)造函數(shù)需要如下參數(shù):
- 顯示抽屜的?Activity?對象
- ?DrawerLayout?對象
- 一個用來指示抽屜的 drawable資源
- 一個用來描述打開抽屜的文本 (用于支持可訪問性)。
- 一個用來描述關(guān)閉抽屜的文本(用于支持可訪問性).
無論你是否繼承?ActionBarDrawerToggle?來實現(xiàn)抽屜監(jiān)聽器,您都需要在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); ????} ????... } |
猛擊我下載示例項目代碼。
?本文出自 云在千峰,轉(zhuǎn)載時請注明出處及相應(yīng)鏈接。
?本文永久鏈接: http://blog.chengyunfeng.com/?p=493
轉(zhuǎn)載于:https://www.cnblogs.com/krislight1105/p/3748369.html
總結(jié)
以上是生活随笔為你收集整理的Navigation Drawer介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 概念:弱监督学习
- 下一篇: WHU 1470 Join in tas