LZ-Says:最近天气渐渐变凉了,终于感受到被子的温暖了。话说这几天的雾霾很是严重啊,能见度也就是几米而已,不知各位小伙伴所处地方如何呢?
前言
说起侧滑效果,大家脑海里首先会想到SlidingMenu,当前LZ也是在这个神器上被坑了很惨,也怪当初自己学艺不精。只从谷歌推出Material Design之后,其包含的内容可谓是丰富多彩,让人爱不释手,而今天,为大家带来新的侧滑实现,也就是Material Design包含的DrawerLayout~
效果图
老规矩,放置效果图,如下:
本文目标
快速有效掌握使用DrawerLayout实现侧滑菜单效果。
先撸一发
1. 初始化布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.widget.DrawerLayout
android:id="@+id/i_drawerlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.materialdesignstudy.drawerlayout.DrawerLayoutActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff0"
android:gravity="center"
android:text="使用DrawerLayout实现侧滑" />
</LinearLayout>
<!-- 左侧侧滑 -->
<LinearLayout
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#fff"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#ff0"
android:padding="15dp"
android:text="哇咔咔" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#ff0"
android:padding="15dp"
android:text="我去" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:background="#ff0"
android:padding="15dp"
android:text="啦啦啦" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="clickMe"
android:text="点我哦~" />
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
这里需要注意的是,假设设置左侧侧滑,那你需要在侧滑内容块的父布局中设置位置,例如我们现在设置的start,如下:
<!-- 左侧侧滑 -->
<LinearLayout
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#fff"
android:orientation="vertical">
好了,设置完基本布局后,运行瞅一眼。
嗯哼,是不是很简单呢?
下面我们配合Toolbar来秀一波。
2.1 布局新增Toolbar
<!-- 这里推荐使用兼容包 -->
<android.support.v7.widget.Toolbar
android:id="@+id/id_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary" />
2.2 初始化并设置监听
mToolBar = findViewById(R.id.id_toolbar);
mDrawerLayout = findViewById(R.id.i_drawerlayout);
// 将ActionBar替换成toolbar
setSupportActionBar(mToolBar);
ActionBarDrawerToggle drawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolBar, R.string.string_open, R.string.string_close);
// 同步状态
drawerToggle.syncState();
// 设置侧滑监听
mDrawerLayout.setDrawerListener(drawerToggle);
查看效果:
上面俩个例子可以看出,DrawerLayout是真的方便快捷,省去不少的事儿,Nice~
下面我们简单的分析下源码,看看从源码中,我们能get什么小技能。
DrawerLayout源码简单分析
首先DrawerLayout extends ViewGroup,也就是说DrawerLayout其实是一个View组,我们可以在这里添加我们自己的View,也就是实际中的各种item项。
在构造初始化中,我们看到如下关键代码:
mLeftCallback = new ViewDragCallback(Gravity.LEFT);
mRightCallback = new ViewDragCallback(Gravity.RIGHT);
mLeftDragger = ViewDragHelper.create(this, TOUCH_SLOP_SENSITIVITY, mLeftCallback);
mLeftDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
mLeftDragger.setMinVelocity(minVel);
mLeftCallback.setDragger(mLeftDragger);
mRightDragger = ViewDragHelper.create(this, TOUCH_SLOP_SENSITIVITY, mRightCallback);
mRightDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_RIGHT);
mRightDragger.setMinVelocity(minVel);
mRightCallback.setDragger(mRightDragger);
文章一开始,我们使用的是左侧滑动监听,但是我们可清晰的看到,同时他也提供了从右侧滑动监听,其次,滑动无论是左右,其依赖关键类便是:ViewDragHelper。
我们可以通过ViewDragHelper去设置一些属性,例如滑动方向,滑动偏移量速度等。
再接着往下看,看到了它的监听项,如下:
/**
* Listener for monitoring events about drawers. 侧滑监听器
*/
public interface DrawerListener {
/**
* 侧滑时位置状态变化
* @param 子视图被移动
* @param slideOffset The new offset of this drawer within its range, from 0-1 偏移量移动(绘制)范围:0-1
*/
public void onDrawerSlide(View drawerView, float slideOffset);
/**
* 开始绘制
*
* @param drawerView Drawer view that is now open
*/
public void onDrawerOpened(View drawerView);
/**
* 结束绘制
*
* @param drawerView Drawer view that is now closed
*/
public void onDrawerClosed(View drawerView);
/**
* 绘制状态改变
*
* @param newState The new drawer motion state
*/
public void onDrawerStateChanged(@State int newState);
}
而关键内容也就是后期我们会根据不同的情况在回调中进行不同的操作,那么上面刚刚提到了可以设置右侧侧滑,那么现在着手实现一下吧。
继续玩~
首先,布局新增块,设置方式为end,关键代码如下:
<!-- 右侧侧滑 -->
<LinearLayout
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:background="#fff"
android:orientation="vertical">
这块需要拓展的是,之前我们使用的是自带的ActionBarDrawerToggle,而通过简单查看源码,我们现在自己玩下监听,如下设置相关动画效果:
mDrawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
// 绘制 slideOffset范围:0~1
View content=mDrawerLayout.getChildAt(0); // 拿到第0个布局
// 设置左侧滑动效果
View menu=drawerView;
float scale=1-slideOffset;
float leftScale= (float) (1-0.3*scale);
menu.setScaleX(leftScale); // 反过来滑动范围是 1~0.7
menu.setScaleY(leftScale); // 反过来滑动范围是 1~0.7
// 设置右侧滑动效果
float rightScale=(float) (0.7+0.3*scale);
content.setScaleX(rightScale);
content.setScaleY(rightScale);
content.setTranslationX(menu.getMeasuredWidth()*(1-scale)); // 0~width
}
@Override
public void onDrawerOpened(View drawerView) {
// 抽屉打开
}
@Override
public void onDrawerClosed(View drawerView) {
// 抽屉被关闭
}
@Override
public void onDrawerStateChanged(int newState) {
// 状态发生改变回调
}
});
嗯哼,现在的效果就达到了文章开头的效果了。
GitHub地址
结束
感谢大家观看~
希望我们越来越好~