DrawerLayout和NavigationView轻松实现抽屉侧滑
2017-07-17 10:25
351 查看
在android5.0后谷歌添加了DrawerLayout和NavigationView两个控件,使用这两个控件可以很轻松的实现抽屉侧滑效果,这里说先DrawerLayout;
DrawerLayout:
DrawerLayout是MateriaDesign风格中的控件,来自support-v4包里面,相当于一个自定义容器 extends ViewGroup ,可以看作是一个有侧滑效果的帧布局。
1、DrawerLayout+ToolBar实现抽屉侧滑
在使用DrawerLayout的时候要将DrawerLayout作为内容布局和侧滑菜单布局的父布,
在侧滑菜单布局中要添加android:layout_gravity=”end”,这样DrawerLayout才会辨别哪个是侧滑菜单,这里提供了是个属性值;
LEFT和START表示左边侧滑,RIGHT和END表示右边侧滑,GravityCompat.START和GravityCompat.END是为了兼容低版本,布局文件写好后,将布局文件中的控件引入进来;
没错就这些代码就已经实现了一个抽屉侧滑效果;
![](http://img.blog.csdn.net/20170724213510792?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FuZ3dvMTk5MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
实现了左右侧滑,点击ToolBar左边可以打开或关闭侧滑菜单,点击条目同样可以响应点击事件;
DrawerLayout单独使用实现抽屉侧滑
如果不想结合ToolBar来实现侧滑效果也是可以的,下面这个就是DrawerLayout单独使用实现抽屉侧滑,布局文件还是一样的没有变化,只是将标题栏改成了RelativeLayout,RelativeLayout里面放了一个imageview,点击imageview或者ListView条目来控制DrawerLayout打开或关闭;
调用DrawerLayout里面的openDrawer或者closeDrawer就可以设置打开还是关闭,不过在设置的时候要注意,GravityCompat.START要和布局文件中的android:layout_gravity=”start”要相对应,这样就可以了;
![](http://img.blog.csdn.net/20170724214416020?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FuZ3dvMTk5MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
注:点击条目打开右边侧滑菜单的效果有点类似于易车网App选车列表效果
如果只是想点击的时候打开侧滑菜单,左右滑动的时候不打开也是可以的,调用setDrawerLockMode();就可以设置打开还是关闭;lockMode参数有四个选择:
第一个和第三个最终还是调用的是第二个;接下来就去看看DrawerLayout的源码;
DrawerLayout源码:
在DrawerLayout构造方法里面可以看到DrawerLayout是利用ViewDragHelper这里类来实现侧滑效果的;在DrawerLayout和ToolBar结合使用的时候还涉及到了ActionBarDrawerToggle类,
ActionBarDrawerToggle类提供了两个构造方法;
调用syncState();方法后就将ToolBar和DrawerLayout同步,
走到这里涉及到DrawerArrowDrawable类,DrawerArrowDrawable extend Drawable,根据传进来的position调用DrawerArrowDrawable 中的setProgress();方法进行绘制;
Drawable类中的invalidateSelf();方法
这样就会在侧滑菜单打开或关闭的时候,对三道杠或者箭头进行切换绘制;如果想在打开或关闭的时候进行监听添加其他效果可以调用DrawerLayout中的setDrawerListener或者addDrawerListener,不过建议调用addDrawerListener,setDrawerListener已经过时了,
如果不想实现全部方法的话可以使用SimpleDrawerListener,SimpleDrawerListener implements DrawerListener;
这样可以根据自己的需要进行方法的重写,其他的一些方法在使用的时候可以细看源码,总的来说DrawerLayout使用起来还是比较灵活的;
NavigationView
NavigationView也是谷歌在android5.0推出来的一个侧滑控价,目的是为了用来规范侧滑的基本样式;NavigationView使用的时候要结合DrawerLayout一起使用;
1、引入依赖库
2、在xml文件中使用
将DrawerLayout作为内容布局和侧滑菜单布局的父布局,使用NavigationView作为侧滑菜单;
这样效果就实现了,是不是比DrawerLayout还要简单;
![](http://img.blog.csdn.net/20170724224308388?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FuZ3dvMTk5MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
但是NavigationView是为了规范侧滑的基本样式的,侧滑菜单的样式就不好改变,条目就只能采用menu的方式实现,使用起来就没有DrawerLayout那么灵活,在开发中,效果不是很炫的话,可以使用DrawerLayout来实现,当前自定义的话也可以。
源码地址:
http://download.csdn.net/detail/wangwo1991/9909251
DrawerLayout:
DrawerLayout是MateriaDesign风格中的控件,来自support-v4包里面,相当于一个自定义容器 extends ViewGroup ,可以看作是一个有侧滑效果的帧布局。
1、DrawerLayout+ToolBar实现抽屉侧滑
在使用DrawerLayout的时候要将DrawerLayout作为内容布局和侧滑菜单布局的父布,
<?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.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimary"> </android.support.v7.widget.Toolbar> <android.support.v4.widget.DrawerLayout android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.drawerlayoutdemo.MainActivity"> <!--内容部分--> <ListView android:id="@+id/content_list" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView> <!--侧滑菜单部分左边--> <ListView android:id="@+id/left" android:layout_width="150dp" android:layout_gravity="start" android:layout_height="match_parent" android:background="@android:color/white"> </ListView> <!--侧滑菜单部分右边--> <ListView android:id="@+id/right" android:layout_width="match_parent" android:layout_marginLeft="50dp" android:layout_gravity="end" android:layout_height="match_parent" android:background="@android:color/white"> </ListView> </android.support.v4.widget.DrawerLayout> </LinearLayout>
在侧滑菜单布局中要添加android:layout_gravity=”end”,这样DrawerLayout才会辨别哪个是侧滑菜单,这里提供了是个属性值;
@IntDef({Gravity.LEFT, Gravity.RIGHT, GravityCompat.START, GravityCompat.END})
LEFT和START表示左边侧滑,RIGHT和END表示右边侧滑,GravityCompat.START和GravityCompat.END是为了兼容低版本,布局文件写好后,将布局文件中的控件引入进来;
drawerLayout= (DrawerLayout) findViewById(R.id.drawer_layout); toolbar= (Toolbar) findViewById(R.id.toolbar); //设置Toolbar setSupportActionBar(toolbar); //将DrawerLayout和Toolbar关联 ActionBarDrawerToggle toggle=new ActionBarDrawerToggle(this,drawerLayout,toolbar,R.string.drawer_open,R.string.drawer_close); //进行同步 toggle.syncState(); //添加事件监听 drawerLayout.addDrawerListener(toggle);
没错就这些代码就已经实现了一个抽屉侧滑效果;
实现了左右侧滑,点击ToolBar左边可以打开或关闭侧滑菜单,点击条目同样可以响应点击事件;
DrawerLayout单独使用实现抽屉侧滑
如果不想结合ToolBar来实现侧滑效果也是可以的,下面这个就是DrawerLayout单独使用实现抽屉侧滑,布局文件还是一样的没有变化,只是将标题栏改成了RelativeLayout,RelativeLayout里面放了一个imageview,点击imageview或者ListView条目来控制DrawerLayout打开或关闭;
iv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { index++; if (index % 2 == 0) { //打开 drawerLayout.openDrawer(GravityCompat.START, true); } else { //关闭 drawerLayout.closeDrawer(GravityCompat.START, true); } } });
调用DrawerLayout里面的openDrawer或者closeDrawer就可以设置打开还是关闭,不过在设置的时候要注意,GravityCompat.START要和布局文件中的android:layout_gravity=”start”要相对应,这样就可以了;
注:点击条目打开右边侧滑菜单的效果有点类似于易车网App选车列表效果
如果只是想点击的时候打开侧滑菜单,左右滑动的时候不打开也是可以的,调用setDrawerLockMode();就可以设置打开还是关闭;lockMode参数有四个选择:
/** * The drawer is unlocked. */ public static final int LOCK_MODE_UNLOCKED = 0; /** * The drawer is locked closed. The user may not open it, though * the app may open it programmatically. */ public static final int LOCK_MODE_LOCKED_CLOSED = 1; /** * The drawer is locked open. The user may not close it, though the app * may close it programmatically. */ public static final int LOCK_MODE_LOCKED_OPEN = 2; /** * The drawer's lock state is reset to default. */ public static final int LOCK_MODE_UNDEFINED = 3;
//设置左边和右边关闭或者打开 public void setDrawerLockMode(@LockMode int lockMode) { setDrawerLockMode(lockMode, Gravity.LEFT); setDrawerLockMode(lockMode, Gravity.RIGHT); }
//设置左边或者右边打开或者关闭 edgeGravity可以是Gravity.LEFT, //Gravity.RIGHT, GravityCompat.START, GravityCompat.END里 //面的任意一个 public void setDrawerLockMode(@LockMode int lockMode, @EdgeGravity int edgeGravity) { ... }
//指定对应的View侧滑打开或者关闭 public void setDrawerLockMode(@LockMode int lockMode, View drawerView) { ... setDrawerLockMode(lockMode, gravity); }
第一个和第三个最终还是调用的是第二个;接下来就去看看DrawerLayout的源码;
DrawerLayout源码:
public DrawerLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); ... 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); ... }
在DrawerLayout构造方法里面可以看到DrawerLayout是利用ViewDragHelper这里类来实现侧滑效果的;在DrawerLayout和ToolBar结合使用的时候还涉及到了ActionBarDrawerToggle类,
ActionBarDrawerToggle类提供了两个构造方法;
public ActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, @StringRes int openDrawerContentDescRes, @StringRes int closeDrawerContentDescRes) { this(activity, null, drawerLayout, null, openDrawerContentDescRes, closeDrawerContentDescRes); }
public ActionBarDrawerToggle(Activity activity, DrawerLayout drawerLayout, Toolbar toolbar, @StringRes int openDrawerContentDescRes, @StringRes int closeDrawerContentDescRes) { this(activity, toolbar, drawerLayout, null, openDrawerContentDescRes, closeDrawerContentDescRes); }
调用syncState();方法后就将ToolBar和DrawerLayout同步,
public void syncState() { if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) { setPosition(1); } else { setPosition(0); } ... }
private void setPosition(float position) { if (position == 1f) { mSlider.setVerticalMirror(true); } else if (position == 0f) { mSlider.setVerticalMirror(false); } mSlider.setProgress(position); }
走到这里涉及到DrawerArrowDrawable类,DrawerArrowDrawable extend Drawable,根据传进来的position调用DrawerArrowDrawable 中的setProgress();方法进行绘制;
public void setProgress(@FloatRange(from = 0.0, to = 1.0) float progress) { if (mProgress != progress) { mProgress = progress; //进行绘制,最终调用父类中的方法进行绘制drawable invalidateSelf(); } }
Drawable类中的invalidateSelf();方法
public void invalidateSelf() { final Callback callback = getCallback(); if (callback != null) { callback.invalidateDrawable(this); } }
这样就会在侧滑菜单打开或关闭的时候,对三道杠或者箭头进行切换绘制;如果想在打开或关闭的时候进行监听添加其他效果可以调用DrawerLayout中的setDrawerListener或者addDrawerListener,不过建议调用addDrawerListener,setDrawerListener已经过时了,
@Deprecated public void setDrawerListener(DrawerListener listener) { //如果之前的DrawerListener还存在就将其移除调 if (mListener != null) { removeDrawerListener(mListener); } //添加新的DrawerListener if (listener != null) { addDrawerListener(listener); } //将新的DrawerListener赋值给之前的DrawerListener mListener = listener; } public void addDrawerListener(@NonNull DrawerListener listener) { if (listener == null) { return; } //利用集合来管理DrawerListener if (mListeners == null) { mListeners = new ArrayList<DrawerListener>(); } mListeners.add(listener); }
//给侧滑控件设置监听 drawerlayout.setDrawerListener(new DrawerListener() { @Override public void onDrawerStateChanged(int newState) { // 状态发生改变 } @Override public void onDrawerSlide(View drawerView, float slideOffset) { // 滑动的过程当中不断地回调 slideOffset:0~1 } @Override public void onDrawerOpened(View drawerView) { // 打开 } @Override public void onDrawerClosed(View drawerView) { // 关闭 } });
如果不想实现全部方法的话可以使用SimpleDrawerListener,SimpleDrawerListener implements DrawerListener;
public abstract static class SimpleDrawerListener implements DrawerListener { @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) { } }
这样可以根据自己的需要进行方法的重写,其他的一些方法在使用的时候可以细看源码,总的来说DrawerLayout使用起来还是比较灵活的;
NavigationView
NavigationView也是谷歌在android5.0推出来的一个侧滑控价,目的是为了用来规范侧滑的基本样式;NavigationView使用的时候要结合DrawerLayout一起使用;
1、引入依赖库
compile 'com.android.support:design:26.0.0-alpha1'
2、在xml文件中使用
将DrawerLayout作为内容布局和侧滑菜单布局的父布局,使用NavigationView作为侧滑菜单;
<?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:layout_width="match_parent" android:layout_height="match_parent"> <!-- 内容部分 --> <FrameLayout android:id="@+id/fl" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <!-- 菜单部分 --> <android.support.design.widget.NavigationView android:layout_gravity="start" android:layout_width="wrap_content" android:layout_height="fill_parent" app:menu="@menu/navigation_menu" app:headerLayout="@layout/navigation_headerlayout" /> </android.support.v4.widget.DrawerLayout>
app:menu 侧滑菜单的条目 app:headerLayout 侧滑菜单条目上面的头部布局
这样效果就实现了,是不是比DrawerLayout还要简单;
但是NavigationView是为了规范侧滑的基本样式的,侧滑菜单的样式就不好改变,条目就只能采用menu的方式实现,使用起来就没有DrawerLayout那么灵活,在开发中,效果不是很炫的话,可以使用DrawerLayout来实现,当前自定义的话也可以。
源码地址:
http://download.csdn.net/detail/wangwo1991/9909251
相关文章推荐
- Android使用DrawerLayout和NavigationView实现侧滑效果
- 基于谷歌官方DrawerLayout实现QQ样式边侧滑抽屉缩进缩出技术
- NavigationView和DrawerLayout实现侧滑菜单栏
- ToolBar+DrawerLayout实现左右双布局侧滑和动画返回控制显示抽屉布局
- 使用DrawerLayout组件实现侧滑抽屉的功能
- Android侧滑菜单DrawerLayout(抽屉布局)实现
- Android实现侧滑抽屉菜单(DrawerLayout+NavigationView+toolbar)
- android 开发 -- NavigationView和DrawerLayout实现 侧滑栏(Material Design)
- Material Design系列风格控件之(二)----NavigationView和DrawerLayout实现侧滑菜单栏
- MaterialDesign之NavigationView和DrawerLayout实现侧滑菜单栏(抽屉)
- 侧滑菜单(抽屉效果)DrawerLayout实现原理
- Android 用 DrawerLayout 和 NavigationView 实现侧滑菜单栏
- 基于谷歌官方DrawerLayout实现QQ样式边侧滑抽屉缩进缩出技术
- DrawerLayout 和NavigationView 实现抽屉式侧滑
- Kotlin实现侧滑抽屉菜单(DrawerLayout+NavigationView+Toolbar)
- Android DrawerLayout和NavigationView实现左右侧滑和自定义toolbar。
- 利用DrawerLayout和触摸事件分发实现抽屉侧滑效果
- [Android基础知识] 之二十: 侧滑菜单DrawerLayout(抽屉布局)实现
- Material Design最佳体验(3):使用DrawerLayout、NavigationView轻松实现滑动菜单
- android 使用ViewDragHelper轻松实现DrawerLayout和SlidMenu侧滑效果