上一讲我们已经实现了在2.x的系统上同时使用ActionBar和Navigation Drawer,但是我们看一下google play的交互:
我们点击右上角的那个向下的小箭头,Navigation Drawer就会跳转到另外一个界面:
这个怎么实现呢?
不知道大家还记不记得我第一讲的内容:
用来显示屏幕主体内容的视图一般是
FrameLayout
(运行的时候,会被一个
Fragment
填充),用来显示导航抽屉的视图一般是一个
ListView
,如下所示
<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>
复制代码
上面的布局说明了导航抽屉的布局一些非常重要的特点:
1
、显示主体内容的视图必须是
DrawerLayout
下的第一个子视图,因为抽屉视图必须在主体内容视图的上方(意味着
DrawerLayout
是一个以
z
轴来布局的控件)
2
、显示主体内容的视图必须设置为匹配父视图的高和宽,因为当抽屉视图隐藏的时候显示主体内容的视图代表了整个用户界面
3
、抽屉视图的
layout_gravity
属性值需为
“start”
,
To support right-to-left (RTL) languages,specify the value with "start" insteadof "left" (so the drawer appears on the right when thelayout is RTL)
4
、抽屉视图的宽度不宜匹配父视图,应当适当的窄一点,这样就能在抽屉显示的时候还能看到主体内容视图的一部分
我们只要遵循这几条规则,就能写出自定义的ui了,下面我模仿google play,写了一个简单的layout:
<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" > <FrameLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent" /> <RelativeLayout android:id="@+id/drawerLayout" android:layout_width="240dp" android:layout_height="match_parent" android:background="#111" android:layout_gravity="start" > <RelativeLayout android:id="@+id/titleLayout" android:layout_width="match_parent" android:layout_height="48dp" android:layout_alignParentTop="true" android:background="@color/abs__background_holo_dark" > <ImageView android:id="@+id/exchange_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_alignParentRight="true" android:background="@drawable/ic_more_arrow_down_dark" android:layout_marginRight="10dp" /> </RelativeLayout> <RelativeLayout android:id="@+id/content_layout" android:layout_below="@id/titleLayout" android:layout_width="match_parent" android:layout_height="match_parent" ></RelativeLayout> </RelativeLayout> </android.support.v4.widget.DrawerLayout>
复制代码
布局中id为
drawerLayout
的布局,就是我们要加载的抽屉视图,大家注意要在这个layout中添加这条属性
android:layout_gravity="start"。
控制抽屉视图的跳转
我们首先给抽屉视图添加一个fragment:
FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.content_layout, new DrawerFragment1(this)); ft.commit();
复制代码
然后监听抽屉视图标题栏的点击事件:
RelativeLayout titleLayout = (RelativeLayout) findViewById(R.id.titleLayout); titleLayout.setOnClickListener(this);
复制代码
我们在监听到用户的点击事件以后,替换fragment:
if(showFirst) { exchange_image.setBackgroundResource(R.drawable.ic_up_white_16); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.content_layout, new DrawerFragment2()); ft.commit(); } else { exchange_image.setBackgroundResource(R.drawable.ic_more_arrow_down_dark); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.replace(R.id.content_layout, new DrawerFragment1(MainActivity.this)); ft.commit(); } showFirst = !showFirst;
复制代码
下面是运行的截图:
点击右上角向下的小箭头以后:
这个时候就弹出了另外一个fragment。
源码下载: