DrawerLayout是官方的一个实现侧滑菜单的控件,可以使用它实现大部分的侧滑效果。
首先在布局中使用DrawerLayout,它继承自VIewGroup,第一个childView就是我们的内容布局,第二个就是我们的菜单,当然也可以有第三个作为第二个菜单
.support.v4.widget.DrawerLayout
android:id="@+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent">
"match_parent"
android:layout_height="match_parent"
android:background="@mipmap/ic_launcher" />
"100dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:tag="left"
android:background="#fff"/>
"100dp"
android:layout_height="match_parent"
android:layout_gravity="right"
android:tag="right"
android:background="#fff"/>
.support.v4.widget.DrawerLayout>
contentView自然是要填充父布局,菜单的width自己设定就好,值得一提的是菜单的android:layout_gravity属性,left表示左菜单,right表示右菜单这很直观,还有一个start属性,官方解释如下
To support right-to-left (RTL) languages, specify the value with”start” instead of “left” (so the drawer appears on the right when the layout is RTL).
listview没有添加数据,背景图片也图省事直接用ic_laucnher,所以看起来比较丑。。。
官方提供了接口DrawerListener,监听drawer的状态,需要重写以下四个个方法
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
}
@Override
public void onDrawerOpened(View drawerView) {
}
@Override
public void onDrawerClosed(View drawerView) {
}
@Override
public void onDrawerStateChanged(int newState) {
}
方法名已经很明显了,在这就不解释了,接下来我们利用这个接口实现一个侧滑特效
代码如下
mDrawer.addDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
// 判断是否左菜单
if (drawerView.getTag().equals("left")) {
// 得到contentView
View content = mDrawer.getChildAt(0);
int offset = (int) (drawerView.getWidth() * slideOffset);
content.setTranslationX(offset);
}
}
@Override
public void onDrawerOpened(View drawerView) {
}
@Override
public void onDrawerClosed(View drawerView) {
}
@Override
public void onDrawerStateChanged(int newState) {
}
});
这里通过布局文件声明的tag属性来判断是哪一个菜单,如果是左菜单,我们就在滑动过程中不断设置content的translationX,这个值是根据菜单的宽度和偏移比例相乘得到的,效果如下
稍加修改就可以实现qq的侧滑效果
mDrawer.addDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
// 判断是否左菜单
if (drawerView.getTag().equals("left")) {
// 得到contentView
View content = mDrawer.getChildAt(0);
int offset = (int) (drawerView.getWidth() * slideOffset);
content.setTranslationX(offset);
content.setScaleX(1 - slideOffset * 0.5f);
content.setScaleY(1 - slideOffset * 0.5f);
}
}
@Override
public void onDrawerOpened(View drawerView) {
}
@Override
public void onDrawerClosed(View drawerView) {
}
@Override
public void onDrawerStateChanged(int newState) {
}
});
}
ActionBarDrawerToggle这个类实现了DrawerListener接口,它的作用就是配合ToolBar使用,这样我们点击ToolBar的home键时,就可以出发drawer。当然,虽然ActionBarDrawerToggle帮我们重写了四个方法,我们不需要重写,我们也可以根据自己需要重写相关方法,代码如下
mToolbar.setTitle("Test");
setSupportActionBar(mToolbar);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mToggle = new ActionBarDrawerToggle(this, mDrawer, mToolbar, R.string.drawer_open, R.string.drawer_close) {
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
View content = mDrawer.getChildAt(0);
if (drawerView.getTag().equals("left")) {
int offset = (int) (drawerView.getWidth() * slideOffset);
content.setTranslationX(offset);
content.setScaleX(1-slideOffset / 2);
content.setScaleY(1-slideOffset / 2);
}
}
@Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
//mToolbar.setTitle("closed");
}
@Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
//mToolbar.setTitle("opened");
}
};
mToggle.syncState();
mDrawer.addDrawerListener(mToggle);
ActionBarDrawerToggle的构造函数第一个是Activity,第二个是DrawerLayout,第三个是ToolBar,接下来两个int我也不知道是什么。mToggle.syncState()方法是同步toolbar与drawerlayout的状态,也就是home的图标会改变,最后当然就是添加监听了,效果如下