DrawerLayout是support.v4包中實現側滑菜單效果的控件,之前實現側滑使用的是SlidingMenu,下面我主要介紹一下DrawerLayout控件。
DrawerLayout的使用非常方便,具體的使用如下所示:
1,drawerLayout 其實就是一個布局控件,跟RelativeLayout差不多,單是drawerLayout是帶有側滑效果的控件。drawerLayout布局里面可以包含兩個布局,主內容布局和側滑布局。
其中主內容布局要寫在側滑布局的前面。
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/id_drawerlayout" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="com.example.mgsd.myapplication.MainActivity" tools:showIn="@layout/activity_main"> <-- 主內容布局 --> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/holo_green_dark"> <ImageView android:id="@+id/iv_main" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/ic_launcher" /> </LinearLayout>
<-- 側滑布局 --> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" android:background="@android:color/holo_red_dark"> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:foregroundGravity="left"></ListView> </LinearLayout> </android.support.v4.widget.DrawerLayout>
注:在側滑菜單的布局部分,一定要設置android:layout_gravity屬性,來設置菜單是從左側還是右側滑出,一般設置android:layout_gravity="start"屬性,從左側滑出。
2,drawerLayout菜單的展開和隱藏可以被DrawerLayout.DrawerListener監聽到,所以可以再打開和關閉的時候完成自己的邏輯,但是如果你還是用Toolbar,建議使用
ActionBarDrawerToggle 來監聽側滑菜單的打開和關閉,ActionBarDrawerToggle實現了DrawerListener,所以他能做DrawerListener可以做的任何事情,同時他還能將drawerLayout的展開和隱藏與actionbar的app 圖標關聯起來,當展開與隱藏的時候圖標有一定的動畫效果,點擊圖標的時候還能展開或者隱藏菜單。
mDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.drawopen, R.string.drawclose) { @Override public void onDrawerOpened(View drawerView) { super.onDrawerOpened(drawerView); toolbar.setTitle("側滑欄");//彈出菜單修改toolbar的title } @Override public void onDrawerClosed(View drawerView) { super.onDrawerClosed(drawerView); toolbar.setTitle("APP FrameWork"); } }; mDrawerToggle.syncState(); drawerLayout.setDrawerListener(mDrawerToggle);
3,側滑菜單內容。
側滑菜單里面可以是任何形式,完全自己設置,例如,上面的布局中我們設置了listview,那樣我們就可以在側滑菜單中展示listview或者更簡單的布局,像是展示圖片,文字等。也可以在側滑菜單中加載Fragment,然后操作fragment,如下所示:
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" android:background="@android:color/holo_red_dark"> <FrameLayout android:id="@+id/framlayout" android:layout_width="match_parent" android:layout_height="match_parent" android:foregroundGravity="left"></FrameLayout> </LinearLayout>
然后創建一個Fragment,使用getSupportFragmentManager().beginTransaction().add(R.id.framlayout, new Fragment()).commit();將Fragment添加到側滑菜單中。
4,主動展開和隱藏菜單欄的方法:
DrawerLayout.closeDrawer方法用於隱藏側邊菜單,DrawerLayout.openDrawer方法用於展開側邊菜單
5.如何在菜單展開或者隱藏的時候更新activity的menu
上面的的第2點講到DrawerLayout.DrawerListener監聽展開與隱藏事件,在監聽的回調方法中我們用invalidateOptionsMenu通知activity重繪menu,然后activity就有機會在onPrepareOptionsMenu方法中更新menu元素的顯示與隱藏
代碼:
/* 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); }
6.如何讓app圖標點擊的時候能夠展開或者隱藏側邊菜單。
一般的想法是在activity的onOptionsItemSelected方法中判斷點擊事件是否來自於app圖標,然后用DrawerLayout.closeDrawer和DrawerLayout.openDrawer來隱藏與展開(參見第4點:在代碼中主動展開與隱藏側邊菜單)。但是drawerLayout提供了更優雅的方式:使用ActionBarDrawerToggle的onOptionsItemSelected方法。該方法activity的onOptionsItemSelected方法中根據傳遞進來的menu item做了上面我們在“一般想法”中提到的事情。用官方的說法是”ActionBarDrawerTogglewill take care of this”。我們只需這樣做就ok了:
Activity中:
@Override public booleanonOptionsItemSelected(MenuItem item) { // The action bar home/up actionshould open or close the drawer. // ActionBarDrawerToggle will takecare of this. if(mDrawerToggle.onOptionsItemSelected(item)) { return true; } ……….//處理其他菜單點擊事件 returnsuper.onOptionsItemSelected(item); }
如果不仔細閱讀官方文檔,估計我們很難看出(mDrawerToggle.onOptionsItemSelected(item)在這里的作用。這也是我剛開始最疑惑的地方效果如下所示。
補充
補充一些東西:前幾天做主題切換,發現結合Toobar和 DrawerLayout使用在左上角會自動生成一個三個橫杠的圖標,由於項目需求,我需要將其改為自定義圖標:然后我查看了ActionBarDrawerToggle的源碼發現:
/** * Enable or disable the drawer indicator. The indicator defaults to enabled. * * <p>When the indicator is disabled, the <code>ActionBar</code> will revert to displaying * the home-as-up indicator provided by the <code>Activity</code>'s theme in the * <code>android.R.attr.homeAsUpIndicator</code> attribute instead of the animated * drawer glyph.</p> * * @param enable true to enable, false to disable */ public void setDrawerIndicatorEnabled(boolean enable) { if (enable != mDrawerIndicatorEnabled) { if (enable) { setActionBarUpIndicator((Drawable) mSlider, mDrawerLayout.isDrawerOpen(GravityCompat.START) ? mCloseDrawerContentDescRes : mOpenDrawerContentDescRes); } else { setActionBarUpIndicator(mHomeAsUpIndicator, 0); } mDrawerIndicatorEnabled = enable; } }
看上面的意思是 使用或者禁止使用系統圖標。
然后也就是說enable是true的時候會走系統的邏輯,展示的是系統圖標,這就是很多人為什么設置actionbar的setHomeAsUpIndicator也不好使的原因,所以我們需要兩步:
mDrawerToggle.setDrawerIndicatorEnabled(false);//設置為false時顯示自己設置的圖標 actionBar.setHomeAsUpIndicator(//自己的圖標);
然后這個時候因為屏蔽了系統操作,所以此時點擊圖標是不會滑出側滑欄的,我們需要自己添加點擊側滑功能:
mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() { @Override public void onClick(View v) { openDrawerLayout(); } });
這樣我們就更換了圖標
項目地址:http://download.csdn.net/detail/jingsummer/9400400