DrawLayout我们应该使用
首先简单过一下DrawerLayout源码(这里截取重点)
1 2 3 4 5 6 7 | public class DrawerLayout extends ViewGroup { ... private final ViewDragHelper mLeftDragger; private final ViewDragHelper mRightDragger; private final ViewDragCallback mLeftCallback; private final ViewDragCallback mRightCallback; ...} |
从源码可以看出DrawLoyout就是从ViewGroup实现,即View的容器。所以直接把DrawerLayout当做一个普通容器使用即可。
DrawerLayout只允许两个直接子View。第一个子View为主View,第二个子View为抽屉View
第二个View我们通常会选择使用NavigationView
下面就是一个简单的DrawerLayout布局
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 | <androidx.drawerlayout.widget.DrawerLayout android:id="@+id/drawer_layout1" android:layout_width="match_parent" android:layout_height="200dp" android:fitsSystemWindows="true" tools:openDrawer="start"> <LinearLayout android:id="@+id/view_1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/btn_2" android:text="test" android:layout_height="200dp" android:layout_width="200dp"/> </LinearLayout> <com.google.android.material.navigation.NavigationView android:id="@+id/view_2" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="false"> <TextView android:id="@+id/text_2" android:text="Hellow word" android:gravity="center" android:layout_height="match_parent" android:layout_width="match_parent"/> </com.google.android.material.navigation.NavigationView> </androidx.drawerlayout.widget.DrawerLayout> |
DrawerLayout 属性和普通控件没什么区别,唯一多的一个就是tools:openDrawer=“start”,其功能辅助Android studio 视图预览。如果配置了tools:openDrawer,那么在视图中我们就能看见抽屉展开后的效果。tools:属性不会编译到apk中,只是作为视图辅助使用。属性start或者end,这个由抽屉视图的打开方向决定。
抽屉视图:即子视图2。作为子视图我们应该告知DrawerLayout的抽屉方向android:layout_gravity=“start”,start:从左边打开,end从右边打开。
NavigationView
在Material Design中,Navigation
drawer导航抽屉,被设计用于应用导航,提供了一种通用的导航方式,体现了设计的一致性。
而NavigationView的典型用途就是配合之前v4包的DrawerLayout,作为其中的Drawer部分,即导航菜单的本体部分。NavigationView是一个导航菜单框架,使用menu资源填充数据,使我们可以更简单高效的实现导航菜单。它提供了不错的默认样式、选中项高亮、分组单选、分组子标题、以及可选的Header。
注意其中NavigationView的两个自定义属性
app:headerLayout接收一个layout,作为导航菜单顶部的Header,可选项。
app:menu接收一个menu,作为导航菜单的菜单项,几乎是必选项,不然这个控件就失去意义了。但也可以在运行时动态改变menu属性。
用于NavigationView的典型menu文件,应该是一个可选中菜单项的集合。其中checked=”true”的item将会高亮显示,这可以确保用户知道当前选中的菜单项是哪个。item的选中状态可以在代码中设置
此处由于我需要尽可能的简化DrawerLayout的使用,所以就不细讲NavigationView。如果需要了解的可以通过
所以最简单的DrawerLayout使用方法:
1 2 3 4 5 6 7 8 9 | <DrawerLayout> <!-- 子视图1,作为DrawerLayout主视图 --> <View1> </View1> <!-- 子视图2,作为DrawerLayout抽屉视图 --> <View2 layout_gravity="start"> </View2> </DrawerLayout> |
下面就是一个最简单的抽屉视图Demo
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 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:fitsSystemWindows="true"> <LinearLayout android:layout_width="match_parent" android:layout_height="200dp" android:background="@drawable/ic_launcher_background"/> <androidx.drawerlayout.widget.DrawerLayout android:id="@+id/drawer_layout1" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <LinearLayout android:id="@+id/content_frame1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/text_0" android:text="我是主视图1" android:gravity="center" android:layout_height="match_parent" android:layout_width="match_parent"/> </LinearLayout> <com.google.android.material.navigation.NavigationView android:id="@+id/nav_view2" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="false"> <TextView android:id="@+id/text_2" android:text="我是抽屉视图" android:gravity="center" android:layout_height="match_parent" android:layout_width="match_parent"/> </com.google.android.material.navigation.NavigationView> </androidx.drawerlayout.widget.DrawerLayout> </LinearLayout> |

包含多DrawerLayout的视图,drawer_item_layout.xml.
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 | <?xml version="1.0" encoding="utf-8"?> <androidx.drawerlayout.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:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <LinearLayout android:id="@+id/content_frame1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/text_0" android:text="我是主视图1" android:gravity="center" android:layout_height="match_parent" android:layout_width="match_parent"/> </LinearLayout> <com.google.android.material.navigation.NavigationView android:id="@+id/nav_view2" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="false"> <TextView android:id="@+id/text_2" android:text="我是展开的抽屉" android:gravity="center" android:layout_height="match_parent" android:layout_width="match_parent"/> </com.google.android.material.navigation.NavigationView> </androidx.drawerlayout.widget.DrawerLayout> |
MainActivity.xml修改成如下:
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 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:fitsSystemWindows="true"> <LinearLayout android:layout_width="match_parent" android:layout_height="200dp" android:background="@drawable/ic_launcher_background"/> <include layout="@layout/drawer_item_layout" android:layout_height="200dp" android:layout_width="match_parent" /> <include layout="@layout/drawer_item_layout" android:layout_height="200dp" android:layout_width="match_parent" /> <include layout="@layout/drawer_item_layout" android:layout_height="200dp" android:layout_width="match_parent" /> </LinearLayout> |

上述视图的抽屉我们都是使用NavigationView,那么能否改用其他的呢?答案是OK的。
下面我们将使用LinearLayout替换NavigationView。
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 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout 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:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:fitsSystemWindows="true"> <LinearLayout android:layout_width="match_parent" android:layout_height="200dp" android:background="@drawable/ic_launcher_background"/> <androidx.drawerlayout.widget.DrawerLayout android:id="@+id/drawer_layout1" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <LinearLayout android:id="@+id/content_frame1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/text_0" android:text="我是主视图1" android:gravity="center" android:layout_height="match_parent" android:layout_width="match_parent"/> </LinearLayout> <LinearLayout android:id="@+id/nav_view2" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="start" android:background="@color/colorPrimaryDark" android:fitsSystemWindows="false"> <TextView android:id="@+id/text_2" android:text="我是展开的抽屉" android:textColor="#ff0000" android:gravity="center" android:layout_height="match_parent" android:layout_width="match_parent"/> </LinearLayout> </androidx.drawerlayout.widget.DrawerLayout> </LinearLayout> |

至于子视图2是否可以使用其他具体更多的View代替,例如FrameLayout那肯定也可以的,因为NavigationView就是从FrameLayout继承而来。
此时DrawerLayout的使用基本就OK了。但是不知道你是否还记得本文一开始就提到过的ViewDragHelper 这才是DrawerLayout实现的关键,下一章我们将对其进行讲解。

