基于Android实现仿QQ5.0侧滑
程序员文章站
2023-12-17 15:32:46
本课程将带领大家通过自定义控件实现qq5.0侧滑菜单,课程将循序渐进,首先实现最普通的侧滑菜单,然后引入属性动画与拖动菜单效果相结合,最终实现qq5.0侧滑菜单效果。通过本...
本课程将带领大家通过自定义控件实现qq5.0侧滑菜单,课程将循序渐进,首先实现最普通的侧滑菜单,然后引入属性动画与拖动菜单效果相结合,最终实现qq5.0侧滑菜单效果。通过本课程大家会对侧滑菜单有更深层次的了解,通过自定义控件和属性动画打造千变万化的侧滑菜单效果
效果图如下所示:
package com.example; import android.os.bundle; import android.support.v7.app.actionbaractivity; import android.view.view; public class mainactivity extends actionbaractivity { private slidingmenu mmenu; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); mmenu = (slidingmenu) findviewbyid(r.id.id_menu); } public void togglemenu(view view) { mmenu.toggle(); } } package com.example; import android.app.activity; import android.content.context; import android.graphics.bitmap; import android.graphics.rect; import android.util.displaymetrics; import android.view.view; import android.view.windowmanager; /** * created by tuhao-pc on 2015/12/28. * 获取屏幕相关的辅助类 */ public class screenutils { private screenutils() { } /** *获取屏幕的高度 * @param context * @return */ public static int getscreenwidth(context context){ windowmanager wm = (windowmanager) context.getsystemservice(context.window_service); displaymetrics outmetrics = new displaymetrics(); wm.getdefaultdisplay().getmetrics(outmetrics); return outmetrics.widthpixels; } /** * 获取屏幕的高度 * @param context * @return */ public static int getscreenheight(context context){ windowmanager wm = (windowmanager) context.getsystemservice(context.window_service); displaymetrics outmetrics = new displaymetrics(); wm.getdefaultdisplay().getmetrics(outmetrics); return outmetrics.heightpixels; } /** * 获取手机状态栏的状态 * @param context * @return */ public static int getstatusheight(context context){ int statusheight = -1; class<?> clazz = null; try { clazz = class.forname("com.android.internal.r$dimen"); object object = clazz.newinstance(); int height = integer.parseint(clazz.getfield("status_bar_height").get(object).tostring()); statusheight = context.getresources().getdimensionpixelsize(height); } catch (classnotfoundexception e) { e.printstacktrace(); } catch (nosuchfieldexception e) { e.printstacktrace(); } catch (instantiationexception e) { e.printstacktrace(); } catch (illegalaccessexception e) { e.printstacktrace(); } return statusheight; } /** * 获取当前屏幕截图,包含状态栏 * * @param activity * @return */ public static bitmap snapshotwithstatusbar(activity activity) { view view = activity.getwindow().getdecorview(); view.setdrawingcacheenabled(true); view.builddrawingcache(); bitmap bmp = view.getdrawingcache(); int width = getscreenwidth(activity); int height = getscreenheight(activity); bitmap bp = null; bp = bitmap.createbitmap(bmp, 0, 0, width, height); view.destroydrawingcache(); return bp; } /** * 获取当前屏幕截图,不包含状态栏 * * @param activity * @return */ public static bitmap snapshotwithoutstatusbar(activity activity) { view view = activity.getwindow().getdecorview(); view.setdrawingcacheenabled(true); view.builddrawingcache(); bitmap bmp = view.getdrawingcache(); rect frame = new rect(); activity.getwindow().getdecorview().getwindowvisibledisplayframe(frame); int statusbarheight = frame.top; int width = getscreenwidth(activity); int height = getscreenheight(activity); bitmap bp = null; bp = bitmap.createbitmap(bmp, 0, statusbarheight, width, height - statusbarheight); view.destroydrawingcache(); return bp; } } package com.example; import android.content.context; import android.content.res.typedarray; import android.util.attributeset; import android.util.typedvalue; import android.view.motionevent; import android.view.viewgroup; import android.widget.horizontalscrollview; import android.widget.linearlayout; import com.nineoldandroids.view.viewhelper; /** * created by tuhao-pc on 2015/12/28. */ public class slidingmenu extends horizontalscrollview{ private int mscreenwidth; private int mmenurightpadding; private int mmenuwidth; private int mhalfmenuwidth; private boolean isopen; private boolean once; private viewgroup mmenu; private viewgroup mcontent; public slidingmenu(context context) { this(context,null); } public slidingmenu(context context, attributeset attrs) { this(context, attrs, 0); } public slidingmenu(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); mscreenwidth = screenutils.getscreenwidth(context); typedarray a = context.gettheme().obtainstyledattributes(attrs,r.styleable.slidingmenu,defstyleattr,0); int count = a.getindexcount(); for(int i = 0;i < count;i++){ int attr = a.getindex(i); switch (attr){ case r.styleable.slidingmenu_rightpadding:{ // 默认是50 mmenurightpadding = a.getdimensionpixelsize(attr, (int) typedvalue.applydimension(typedvalue.complex_unit_dip,50f,getresources().getdisplaymetrics())); break; } } } a.recycle(); } @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { /** * 显示设置一个宽度 */ if(!once){ linearlayout wrapper = (linearlayout) getchildat(0); mmenu = (viewgroup) wrapper.getchildat(0); mcontent = (viewgroup) wrapper.getchildat(1); mmenuwidth = mscreenwidth - mmenurightpadding; mhalfmenuwidth = mmenuwidth/2; mmenu.getlayoutparams().width = mmenuwidth; mcontent.getlayoutparams().width = mscreenwidth; } super.onmeasure(widthmeasurespec, heightmeasurespec); } @override protected void onlayout(boolean changed, int l, int t, int r, int b) { super.onlayout(changed, l, t, r, b); if(changed) { // 将菜单隐藏 this.scrollto(mmenuwidth, 0); once = true; } } @override public boolean ontouchevent(motionevent ev) { int action = ev.getaction(); switch (action){ // up时,进行判断,如果显示区域大于菜单宽度一半则完全显示,否则隐藏 case motionevent.action_up:{ int scrollx = getscrollx(); if(scrollx > mhalfmenuwidth){ this.smoothscrollto(mmenuwidth,0); isopen = false; } else{ this.smoothscrollto(0,0); isopen = true; } return true; } } return super.ontouchevent(ev); } /** * 打开菜单 */ public void openmenu() { if (isopen) return; this.smoothscrollto(0, 0); isopen = true; } /** * 关闭菜单 */ public void closemenu() { if (isopen) { this.smoothscrollto(mmenuwidth, 0); isopen = false; } } /** * 切换菜单状态 */ public void toggle() { if (isopen) { closemenu(); } else { openmenu(); } } @override protected void onscrollchanged(int l, int t, int oldl, int oldt) { super.onscrollchanged(l, t, oldl, oldt); float scale = l * 1.0f / mmenuwidth; float leftscale = 1 - 0.3f * scale; float rightscale = 0.8f + scale * 0.2f; viewhelper.setscalex(mmenu, leftscale); viewhelper.setscaley(mmenu, leftscale); viewhelper.setalpha(mmenu, 0.6f + 0.4f * (1 - scale)); viewhelper.settranslationx(mmenu, mmenuwidth * scale * 0.7f); viewhelper.setpivotx(mcontent, 0); viewhelper.setpivoty(mcontent, mcontent.getheight() / 2); viewhelper.setscalex(mcontent, rightscale); viewhelper.setscaley(mcontent, rightscale); } }
布局文件和资源文件(xml)
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tu = "http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.slidingmenu android:id="@+id/id_menu" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@mipmap/img_frame_background" tu:rightpadding="20dp"> <linearlayout android:layout_width="wrap_content" android:layout_height="fill_parent" android:orientation="horizontal" > <include layout="@layout/layout_menu" /> <linearlayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@mipmap/qq" > <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onclick="togglemenu" android:text="切换菜单" /> </linearlayout> </linearlayout> </com.example.slidingmenu> </linearlayout> <?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="#0000" > <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="@mipmap/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="@mipmap/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="@mipmap/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="@mipmap/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="第一个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="@mipmap/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>
推荐阅读
-
基于Android实现仿QQ5.0侧滑
-
Android使用Item Swipemenulistview实现仿QQ侧滑删除功能
-
Android recyclerview实现拖拽排序和侧滑删除
-
Android基于API的Tabs3实现仿优酷tabhost效果实例
-
Android开源AndroidSideMenu实现抽屉和侧滑菜单
-
Android自定义View 仿QQ侧滑菜单的实现代码
-
Android使用Item Swipemenulistview实现仿QQ侧滑删除功能
-
代码分析Android实现侧滑菜单
-
Android Drawerlayout实现侧滑菜单效果
-
Android仿淘宝头条基于TextView实现上下滚动通知效果