Android使用DrawerLayout实现仿QQ双向侧滑菜单
1、概述
之前写了一个android 高仿 qq5.0 侧滑菜单效果 自定义控件来袭 ,恰逢qq5.2又加了一个右侧菜单,刚好看了下drawerlayout,一方面官方的东西,我都比较感兴趣;另一方面,这玩意用起来的确方便,于是简单写了个demo,高仿qq5.2双向侧滑,分享给大家。
首先看看效果图:
drawerlayout用起来真的很方便,下面一起看看用法~
2、drawerlayout的使用
直接将drawerlayout作为根布局,然后其内部第一个view为内容区域,第二个view为左侧菜单,第三个view为右侧侧滑菜单,当前第三个是可选的。
第一个view的宽高应当设置为match_parent,当然了,这也理所当然。
第二、三个view需要设置android:layout_gravity="left",和android:layout_gravity="right"且一搬高度设置为match_parent,宽度为固定值,即侧滑菜单的宽度。
按照上面的描述写个布局文件,然后设置给activity就添加好了左右侧滑了,是不是很简单~~~
比如我们的布局文件:
<android.support.v4.widget.drawerlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/id_drawerlayout" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/img_frame_background" > <relativelayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/qq" > <button android:layout_width="40dp" android:layout_height="30dp" android:layout_margintop="10dp" android:layout_alignparentright="true" android:background="@drawable/youce" android:onclick="openrightmenu" /> </relativelayout> <fragment android:id="@+id/id_left_menu" android:name="com.zhy.demo_zhy_17_drawerlayout.menuleftfragment" android:layout_width="200dp" android:layout_height="match_parent" android:layout_gravity="left" android:tag="left" /> <fragment android:id="@+id/id_right_menu" android:name="com.zhy.demo_zhy_17_drawerlayout.menurightfragment" android:layout_width="100dp" android:layout_height="match_parent" android:layout_gravity="right" android:tag="right" /> </android.support.v4.widget.drawerlayout>
这里我们的主内容区域为relativelayout
菜单用的两个fragment,左侧为200dp,右侧为100dp;
好了,看了我们的布局文件,接下来看下我们的详细代码。
3、代码是最好的老师
1、menuleftfragment
package com.zhy.demo_zhy_17_drawerlayout; import android.os.bundle; import android.support.v4.app.fragment; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; public class menuleftfragment extends fragment { @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { return inflater.inflate(r.layout.layout_menu, container, false); } }
对应的布局文件:
<?xml version="1.0" encoding="utf-8"?> <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#00000000" > <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centervertical="true" android:orientation="vertical" > <relativelayout android:layout_width="match_parent" android:layout_height="wrap_content" > <imageview android:id="@+id/one" android:layout_width="50dp" android:layout_height="50dp" android:layout_centervertical="true" android:layout_marginleft="20dp" android:layout_margintop="20dp" android:src="@drawable/img_1" /> <textview android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centervertical="true" android:layout_marginleft="20dp" android:layout_torightof="@id/one" android:text="第1个item" android:textcolor="#f0f0f0" android:textsize="20sp" /> </relativelayout> <relativelayout android:layout_width="match_parent" android:layout_height="wrap_content" > <imageview android:id="@+id/two" android:layout_width="50dp" android:layout_height="50dp" android:layout_centervertical="true" android:layout_marginleft="20dp" android:layout_margintop="20dp" android:src="@drawable/img_2" /> <textview android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centervertical="true" android:layout_marginleft="20dp" android:layout_torightof="@id/two" android:text="第2个item" android:textcolor="#f0f0f0" android:textsize="20sp" /> </relativelayout> <relativelayout android:layout_width="match_parent" android:layout_height="wrap_content" > <imageview android:id="@+id/three" android:layout_width="50dp" android:layout_height="50dp" android:layout_centervertical="true" android:layout_marginleft="20dp" android:layout_margintop="20dp" android:src="@drawable/img_3" /> <textview android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centervertical="true" android:layout_marginleft="20dp" android:layout_torightof="@id/three" android:text="第3个item" android:textcolor="#f0f0f0" android:textsize="20sp" /> </relativelayout> <relativelayout android:layout_width="match_parent" android:layout_height="wrap_content" > <imageview android:id="@+id/four" android:layout_width="50dp" android:layout_height="50dp" android:layout_centervertical="true" android:layout_marginleft="20dp" android:layout_margintop="20dp" android:src="@drawable/img_4" /> <textview android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centervertical="true" android:layout_marginleft="20dp" android:layout_torightof="@id/four" android:text="第4个item" android:textcolor="#f0f0f0" android:textsize="20sp" /> </relativelayout> <relativelayout android:layout_width="match_parent" android:layout_height="wrap_content" > <imageview android:id="@+id/five" android:layout_width="50dp" android:layout_height="50dp" android:layout_centervertical="true" android:layout_marginleft="20dp" android:layout_margintop="20dp" android:src="@drawable/img_5" /> <textview android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_centervertical="true" android:layout_marginleft="20dp" android:layout_torightof="@id/five" android:text="第5个item" android:textcolor="#f0f0f0" android:textsize="20sp" /> </relativelayout> </linearlayout> </relativelayout>
其实就是堆出来的布局~~没撒意思~
2、menurightfragment
package com.zhy.demo_zhy_17_drawerlayout; import android.os.bundle; import android.support.v4.app.fragment; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; public class menurightfragment extends fragment { @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { return inflater.inflate(r.layout.menu_layout_right, container, false); } }
对应布局文件:
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_vertical" android:orientation="vertical" > <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centervertical="true" android:layout_gravity="center_vertical" android:layout_marginbottom="20dp" android:orientation="vertical" > <imageview android:layout_width="60dp" android:layout_height="60dp" android:layout_gravity="center" android:src="@drawable/wode" /> <textview android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:text="扫一扫" android:textcolor="#ffffff" /> </linearlayout> <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centervertical="true" android:layout_gravity="center_vertical" android:layout_marginbottom="20dp" android:orientation="vertical" > <imageview android:layout_width="60dp" android:layout_height="60dp" android:layout_gravity="center" android:src="@drawable/saoma" /> <textview android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:text="讨论组" android:textcolor="#ffffff" /> </linearlayout> <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centervertical="true" android:layout_gravity="center_vertical" android:layout_marginbottom="20dp" android:orientation="vertical" > <imageview android:layout_width="60dp" android:layout_height="60dp" android:layout_gravity="center" android:src="@drawable/wode" /> <textview android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:text="扫一扫" android:textcolor="#ffffff" /> </linearlayout> <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centervertical="true" android:layout_gravity="center_vertical" android:layout_marginbottom="20dp" android:orientation="vertical" > <imageview android:layout_width="60dp" android:layout_height="60dp" android:layout_gravity="center" android:src="@drawable/saoma" /> <textview android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:text="讨论组" android:textcolor="#ffffff" /> </linearlayout> </linearlayout>
依旧很简单,除了图标比较难找以外~~
3、mainactivity
mainactivity的布局文件已经贴过了~~
package com.zhy.demo_zhy_17_drawerlayout; import android.os.bundle; import android.support.v4.app.fragmentactivity; import android.support.v4.widget.drawerlayout; import android.support.v4.widget.drawerlayout.drawerlistener; import android.view.gravity; import android.view.view; import android.view.window; import com.nineoldandroids.view.viewhelper; public class mainactivity extends fragmentactivity { private drawerlayout mdrawerlayout; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); requestwindowfeature(window.feature_no_title); setcontentview(r.layout.activity_main); initview(); initevents(); } public void openrightmenu(view view) { mdrawerlayout.opendrawer(gravity.right); mdrawerlayout.setdrawerlockmode(drawerlayout.lock_mode_unlocked, gravity.right); } private void initevents() { mdrawerlayout.setdrawerlistener(new drawerlistener() { @override public void ondrawerstatechanged(int newstate) { } @override public void ondrawerslide(view drawerview, float slideoffset) { view mcontent = mdrawerlayout.getchildat(0); view mmenu = drawerview; float scale = 1 - slideoffset; float rightscale = 0.8f + scale * 0.2f; if (drawerview.gettag().equals("left")) { float leftscale = 1 - 0.3f * scale; viewhelper.setscalex(mmenu, leftscale); viewhelper.setscaley(mmenu, leftscale); viewhelper.setalpha(mmenu, 0.6f + 0.4f * (1 - scale)); viewhelper.settranslationx(mcontent, mmenu.getmeasuredwidth() * (1 - scale)); viewhelper.setpivotx(mcontent, 0); viewhelper.setpivoty(mcontent, mcontent.getmeasuredheight() / 2); mcontent.invalidate(); viewhelper.setscalex(mcontent, rightscale); viewhelper.setscaley(mcontent, rightscale); } else { viewhelper.settranslationx(mcontent, -mmenu.getmeasuredwidth() * slideoffset); viewhelper.setpivotx(mcontent, mcontent.getmeasuredwidth()); viewhelper.setpivoty(mcontent, mcontent.getmeasuredheight() / 2); mcontent.invalidate(); viewhelper.setscalex(mcontent, rightscale); viewhelper.setscaley(mcontent, rightscale); } } @override public void ondraweropened(view drawerview) { } @override public void ondrawerclosed(view drawerview) { mdrawerlayout.setdrawerlockmode( drawerlayout.lock_mode_locked_closed, gravity.right); } }); } private void initview() { mdrawerlayout = (drawerlayout) findviewbyid(r.id.id_drawerlayout); mdrawerlayout.setdrawerlockmode(drawerlayout.lock_mode_locked_closed, gravity.right); } }
嗯,代码基本没什么注释~~维撒呢?是因为的确没什么好注释的。
提几点:
1、为了模拟qq的右侧菜单需要点击才能出现,所以在初始化drawerlayout的时候,使用了mdrawerlayout.setdrawerlockmode(drawerlayout.lock_mode_locked_closed,gravity.right);意思是只有编程才能将其弹出。
然后在弹出以后,需要让手势可以滑动回去,所以在openrightmenu中又编写了:
mdrawerlayout.setdrawerlockmode(drawerlayout.lock_mode_unlocked,gravity.right); unlock了一下。
最后在ondrawerclosed回调中,继续设置mdrawerlayout.setdrawerlockmode(drawerlayout.lock_mode_locked_closed,gravity.right);
2、动画效果
动画用了nineoldandroids,关于动画各种偏移量、缩放比例的计算请参考android 高仿 qq5.0 侧滑菜单效果 自定义控件来袭 基本是一致的,唯一的不同的地方,给content设置了viewhelper.settranslationx(mcontent, mmenu.getmeasuredwidth() * (1 - scale));让content在菜单的右侧,默认情况下menu在菜单之上,所以我们根据菜单划出的距离给content设置x方向的偏移量。
好了,其实看到可以这么做,基本上任何的侧滑菜单效果都能写出来了。有兴趣的话,可以拿drawerlayout实现这篇博客的所有效果:android 实现形态各异的双向侧滑菜单 自定义控件来袭 。
3、setdrawerlistener
通过代码也能看出来,可以使用setdrawerlistener监听菜单的打开与关闭等等。这里对于当前操作是哪个菜单的判断是通过tag判断的,我觉得使用gravity应该也能判断出来~~
好了,没撒了,由于drawerlayout默认只能从边界划出菜单,但是qq划出菜单的手势区域比较大,大家有兴趣,可以重写activity的ontouchevent,在里面判断,如果是左右滑动手势神马的,弹出菜单,应该不麻烦~~~
推荐阅读
-
Android使用DrawerLayout实现仿QQ双向侧滑菜单
-
基于Android实现仿QQ5.0侧滑
-
Android自定义View 仿QQ侧滑菜单的实现代码
-
Android之侧滑菜单DrawerLayout的使用介绍
-
基于Android实现仿QQ5.0侧滑
-
Android使用Item Swipemenulistview实现仿QQ侧滑删除功能
-
Android自定义View 仿QQ侧滑菜单的实现代码
-
Android使用Item Swipemenulistview实现仿QQ侧滑删除功能
-
Android Drawerlayout实现侧滑菜单效果
-
Android中DrawerLayout实现侧滑菜单效果