我们通过一个完整的例子来学习DrawerLayout。
先来看一下这个例子的效果:
首先创建一个项目,在activity_main中加入一下代码:
<?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"
android:id="@+id/drawerLayout"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/content" android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
这里我们在最外层使用了DrawerLayout作为根布局,里面包含两部分:
一个是内容部分,我们通过include引入content这个layout,content里面的内容暂时为空;还有一个是侧滑菜单,我们使用NavigationView来构建这个菜单,NavigationView中最重要的属性是:
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer"
这两条属性引用了两个布局:
首先nav_header_main的内容是:
<?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"
android:orientation="vertical"
android:layout_width="match_parent"
//侧滑菜单的头部高度
android:layout_height="160dp"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:background="@color/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView android:id="@+id/imageView" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="16dp" app:srcCompat="@android:drawable/sym_def_app_icon" />
<TextView android:layout_width="match_parent" android:layout_height="wrap_content"
android:paddingTop="16dp" android:text="Android Studio"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
<TextView android:id="@+id/textView" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="android.studio@android.com" />
</LinearLayout>
通过代码我们可以看出,这是侧滑菜单的头部部分,通过设置layout_height的高度设置侧滑菜单的头部高度。
然后是activity_main_drawer:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single" >
<item
android:icon="@mipmap/ic_launcher"
android:id="@+id/menu1"
android:title="menu1" />
<item
android:icon="@mipmap/ic_launcher"
android:id="@+id/menu2"
android:title="menu2" />
<item
android:icon="@mipmap/ic_launcher"
android:id="@+id/menu3"
android:title="menu3" />
<item
android:icon="@mipmap/ic_launcher"
android:id="@+id/menu4"
android:title="menu4" />
</group>
</menu>
这是侧滑菜单的选项,通过menu实现。
最后我们在MainActivity中设置NavigationView的监听事件:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu1:
break;
case R.id.menu2:
break;
case R.id.menu3:
break;
case R.id.menu4:
break;
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawerLayout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
});
}
DrawerLayout的用法到这里就算结束了,下面我们把DrawerLayout和Toolbar结合起来使用。
首先在content的布局中加入以下代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
</LinearLayout>
接着在MainActivity中设置toolbar与DrawerLayout绑定:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Toolbar与DrawerLayout绑定
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawerLayout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
//侧滑菜单的监听事件
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu1:
break;
case R.id.menu2:
break;
case R.id.menu3:
break;
case R.id.menu4:
break;
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawerLayout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
});
}
我们来看一下效果:
介绍一个小技巧,上面的侧滑菜单在滑动时会遮挡住content部分,我们可以对DrawerLayout设置一个监听,根据DrawerLayout滑动的距离移动content布局。
drawer.addDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
//内容主布局
LinearLayout content = (LinearLayout) findViewById(R.id.content);
content.setTranslationX(slideOffset*drawerView.getWidth());
}
@Override
public void onDrawerOpened(View drawerView) {
}
@Override
public void onDrawerClosed(View drawerView) {
}
@Override
public void onDrawerStateChanged(int newState) {
}
});
效果如下:
加:
偶然又发现一个东西:
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close){
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
LinearLayout content = (LinearLayout) findViewById(R.id.content);
content.setTranslationX(slideOffset*drawerView.getWidth());
}
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
}
};
drawer.addDrawerListener(toggle);
toggle.syncState();
通过上面的形式也可做成一样的效果,并且我发现一个有趣的现象,把onDrawerSlide监听事件的super()方法注释掉,home按钮的动画效果就消失了:
在把onDrawerOpened的super()方法注释掉,home按钮就一直是三条杠的状态:
不注释onDrawerOpened的super()方法,而注释onDrawerClosed的super()方法就一直是箭头的状态。
把所有的super()方法都注释掉,home按钮就一直是三条杠的状态。
具体原因要阅读源码才知道,以后再说吧。