前言


2013 google IO当天,Android团队更新了Android Support Library,在新版本V13中新加入了几个比较重要的功能:

  • 添加DrawerLayout控件,支持创建Navigation Drawer模式。可以设置从左边划出菜单或者右边,也可以左右菜单同时存在。
  • 添加SlidingPaneLayout控件来支持各种屏幕上的摘要、详情界面模式。比如Gmail邮件列表和单个邮件详情界面。当在手机上显示的时候,邮件列表和详情界面分别为两个界面;当在平板上显示的时候,则为一个界面。
  • 添加ActionBarDrawerToggle工具类,方便把DrawerLayoutActionBar功能结合起来。



DrawerLayout


创建DrawerLayout

在需要抽屉菜单的界面,用DrawerLayout作为界面根控件。在DrawerLayout里第一个View为当前界面主内容;第二个和第三个View为抽屉菜单内容。如果当前界面只需要一个抽屉菜单,则第三个View可以省略。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<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 -->
<ScrollView android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start" />
</android.support.v4.widget.DrawerLayout>

注意:

  1. 界面主内容的View必须是DrawerLayout的第一个子View,原因在于XML布局文件中的View顺序为Android系统中的z-ordering顺序,而抽屉必须出现在内容之上。
  2. 界面主内容的View宽度和高度要设置为和DrawerLayout一样,原因在于当抽屉菜单不可见的时候,界面内容代表整个界面UI。
  3. 抽屉菜单(上面的ScrollView)必须使用android:layout_gravity=”start”(当在LTR语言运行时菜单出现在左侧,而RTL语言运行时菜单出现在右侧)。
  4. 抽屉菜单的宽度应该不超过屏幕宽度,这样用户可以在菜单打开的时候看到部分内容界面。



初始化DrawerLayout

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private void initDrawLayout() {
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerLayout.setDrawerListener(new DrawerListener() {
@Override
public void onDrawerClosed(View view) {
}
@Override
public void onDrawerOpened(View view) {
}
@Override
public void onDrawerSlide(View view, float slideOffset) {
}
@Override
public void onDrawerStateChanged(int state) {
}
});
}



开关DrawerLayout

在用DrawerLayout实现侧滑菜单后,一般情况下就不需要额外显示菜单了,也就是可以把原先的菜单响应事件处理为显示侧滑菜单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
return false;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (KeyEvent.KEYCODE_MENU == keyCode && !event.isLongPress()) {
toggleDrawerLayout();
}
return super.onKeyUp(keyCode, event);
}
private void toggleDrawerLayout() {
if (mDrawerLayout != null) {
if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
mDrawerLayout.closeDrawers();
} else {
mDrawerLayout.openDrawer(Gravity.START);
}
}
}



响应DrawerLayout点击

因为DrawerLayout中可以放置任意的View,所以响应事件就参照原有的findViewById加上setOnClickListener即可。当然,如果闲findViewById太繁琐,那么可以看看Android EasyAdapter是否符合你的胃口。



注意事项


[1] 如果在源码编译中引用jar包需要在项目的Android.mk中添加:

1
2
LOCAL_STATIC_JAVA_LIBRARIES += android-support-v13
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES += android-support-v13:libs/android-support-v13.jar

[2] 如果使用了代码混淆,并且编译提示android support相关的warning的话,要在proguard.flags文件中添加:

1
-dontwarn android.support.**

留言