Android实现3种侧滑效果(仿qq侧滑、抽屉侧滑、普通侧滑)
程序员文章站
2023-10-26 20:40:16
自己实现了一下侧滑的三种方式(注释都写代码里了)
本文demo下载地址:andriod侧滑
本文实现所需框架:nineoldandroids下载地址:
1.普通...
自己实现了一下侧滑的三种方式(注释都写代码里了)
本文demo下载地址:andriod侧滑
本文实现所需框架:nineoldandroids下载地址:
1.普通侧滑:
主要是基于horizontalscrollview做的:示例代码如下
主要布局:
<?xml version="1.0" encoding="utf-8"?> <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:gaoyu="http://schemas.android.com/apk/res/gaoyu.com.myapplication" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_qqsideslip" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="gaoyu.com.myapplication.sideslip.qqsideslipactivity"> <!--xmlns:gaoyu自定义命名空间 原有到res+包名--> <gaoyu.com.myapplication.sideslip.slidingmenu_qq android:id="@+id/slmenu_sideslip" android:layout_width="wrap_content" android:layout_height="fill_parent" gaoyu:rightpadding="100dp"> <linearlayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal"> <include layout="@layout/sideslip_menu" /> <!--这个linearlayout就是content--> <linearlayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/sliding"> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onclick="onclick_sideslip_qq" android:text="切换菜单" /> </linearlayout> </linearlayout> </gaoyu.com.myapplication.sideslip.slidingmenu_qq> </relativelayout>
菜单的布局
<?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:orientation="vertical"> <linearlayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_centerinparent="true"> <relativelayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <imageview android:id="@+id/iv_sideslip1" android:layout_width="50dp" android:layout_height="50dp" android:layout_margintop="20dp" android:layout_marginbottom="20dp" android:layout_marginleft="20dp" android:src="@drawable/icon"/> <textview android:layout_centervertical="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_torightof="@+id/iv_sideslip1" android:layout_marginleft="20dp" android:text="第一个item"/> </relativelayout> <relativelayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <imageview android:id="@+id/iv_sideslip2" android:layout_width="50dp" android:layout_height="50dp" android:layout_margintop="20dp" android:layout_marginbottom="20dp" android:layout_marginleft="20dp" android:src="@drawable/icon"/> <textview android:layout_centervertical="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_torightof="@+id/iv_sideslip2" android:layout_marginleft="20dp" android:text="第二个item"/> </relativelayout><relativelayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <imageview android:id="@+id/iv_sideslip3" android:layout_width="50dp" android:layout_height="50dp" android:layout_margintop="20dp" android:layout_marginbottom="20dp" android:layout_marginleft="20dp" android:src="@drawable/icon"/> <textview android:layout_centervertical="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_torightof="@+id/iv_sideslip3" android:layout_marginleft="20dp" android:text="第三个item"/> </relativelayout><relativelayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <imageview android:id="@+id/iv_sideslip4" android:layout_width="50dp" android:layout_height="50dp" android:layout_margintop="20dp" android:layout_marginbottom="20dp" android:layout_marginleft="20dp" android:src="@drawable/icon"/> <textview android:layout_centervertical="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_torightof="@+id/iv_sideslip4" android:layout_marginleft="20dp" android:text="第四个item"/> </relativelayout><relativelayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <imageview android:id="@+id/iv_sideslip5" android:layout_width="50dp" android:layout_height="50dp" android:layout_margintop="20dp" android:layout_marginbottom="20dp" android:layout_marginleft="20dp" android:src="@drawable/icon"/> <textview android:layout_centervertical="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_torightof="@+id/iv_sideslip5" android:layout_marginleft="20dp" android:text="第五个item"/> </relativelayout> </linearlayout> </relativelayout>
定义view类
public class slidingmenu_qq extends horizontalscrollview { private linearlayout mwapper; private viewgroup mmenu; private viewgroup mcontent; //menu的宽度 private int mmenuwidth; //屏幕的宽度(内容区的宽度就是屏幕宽度) private int mscreenwdith; //菜单与右边的距离50dp private int mmenurightpidding = 50; //调用一次 private boolean once; //标识状态 private boolean isopen; /** * 未使用自定义属性时调用 * 由于设置了attr所以... * * @param context * @param attrs */ public slidingmenu_qq(context context, attributeset attrs) { //调用三个参数的构造方法 this(context, attrs, 0); //获取屏幕宽度(窗口管理器) /*windowmanager wm = (windowmanager) context.getsystemservice(context.window_service); //展示度量 displaymetrics outmetrics = new displaymetrics(); wm.getdefaultdisplay().getmetrics(outmetrics); mscreenwdith = outmetrics.widthpixels; //把dp转换成px mmenurightpidding = (int) typedvalue.applydimension(typedvalue.complex_unit_dip, 50, context.getresources().getdisplaymetrics()); */ } /** * 当实现自定义属性时会执行三个参数的方法 * * @param context * @param attrs * @param defstyleattr */ public slidingmenu_qq(context context, attributeset attrs, int defstyleattr) { super(context, attrs, defstyleattr); //获取自定义的属性 typedarray a = context.gettheme().obtainstyledattributes(attrs, r.styleable.slidingmenu_qq, defstyleattr, 0); //自定义属性个数 int n = a.getindexcount(); for (int i = 0; i < n; i++) { int attr = a.getindex(i); switch (attr) { case r.styleable.slidingmenu_qq_rightpadding: //设置默认值是50dp mmenurightpidding = a.getdimensionpixelsize(attr, (int) typedvalue.applydimension(typedvalue.complex_unit_dip, 50, context.getresources().getdisplaymetrics())); break; } } //释放一下 a.recycle(); //获取屏幕宽度(窗口管理器) windowmanager wm = (windowmanager) context.getsystemservice(context.window_service); //展示度量 displaymetrics outmetrics = new displaymetrics(); wm.getdefaultdisplay().getmetrics(outmetrics); mscreenwdith = outmetrics.widthpixels; } /** * new 一个textview时传一个上下文 * * @param context */ public slidingmenu_qq(context context) { //调用两个参数的构造方法 super(context, null); } /** * 设置horizontalscrollview子view的宽和高 * 设置horizontalscrollview自己的宽和高 * * @param widthmeasurespec * @param heightmeasurespec */ @override protected void onmeasure(int widthmeasurespec, int heightmeasurespec) { //设置循环之调用一次 if (!once) { //horizontalscrollview 内部只能有一个元素 所以直接get(0)就行就是那个linerlayout mwapper mwapper = (linearlayout) getchildat(0); //获取mwapper里的第一个元素menu mmenu = (viewgroup) mwapper.getchildat(0); //获取mwapper里的第二个元素content mcontent = (viewgroup) mwapper.getchildat(1); //菜单和内容宽度 mmenuwidth = mmenu.getlayoutparams().width = mscreenwdith - mmenurightpidding; mcontent.getlayoutparams().width = mscreenwdith; //由于子对象被设置了,mwapper就先不用了 once = true; } super.onmeasure(widthmeasurespec, heightmeasurespec); } /** * 通过设置偏移量 将menu隐藏 * @param changed * @param l * @param t * @param r * @param b */ @override protected void onlayout(boolean changed, int l, int t, int r, int b) { super.onlayout(changed, l, t, r, b); //限制多次调用 if (changed) { //x为正滚动条向右 内容向左(移动mmenuwidth 正好将菜单隐藏) this.scrollto(mmenuwidth, 0); } } /** * 判断将菜单滑出来多少了 * * @param ev * @return */ @override public boolean ontouchevent(motionevent ev) { int action = ev.getaction(); switch (action) { case motionevent.action_up: //隐藏在左边的宽度 int scrollx = getscrollx(); if (scrollx >= mmenuwidth / 2) { //scrollto也行但是动画效果不好 (隐藏) 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) return; this.smoothscrollto(mmenuwidth, 0); isopen = false; } /** * 切换菜单 */ public void toggle(){ if (isopen){ closemenu(); }else { openmenu(); } } }
2.抽屉侧滑(添加此方法)
/** * 实现抽屉滑动 * l隐藏在左边的宽度 * 后边是变化梯度 */ @override protected void onscrollchanged(int l, int t, int oldl, int oldt) { super.onscrollchanged(l, t, oldl, oldt); float scale = l*1.0f/mmenuwidth;//1~0梯度的值 //调用属性动画 viewhelper.settranslationx(mmenu,mmenuwidth*scale); }
3.qq5.0侧滑,实现这个方法
/** * 实现仿qq5.0 * l等于隐藏在左边的宽度(越来越小) * 后边是变化梯度 */ @override protected void onscrollchanged(int l, int t, int oldl, int oldt) { super.onscrollchanged(l, t, oldl, oldt); float scale = l * 1.0f / mmenuwidth;//1~0梯度的值 //调用属性动画 //菜单的缩放操作 float leftscale = 1.0f-scale*0.3f; //透明度 float leftalpha = 0.6f + 0.4f*(1-scale); viewhelper.settranslationx(mmenu, mmenuwidth * scale*0.8f); viewhelper.setscalex(mmenu,leftscale); viewhelper.setscaley(mmenu,leftscale); viewhelper.setalpha(mmenu,leftalpha); //内容区域不断缩小 float rightscale = 0.7f+0.3f*scale; //横向纵向缩放(不更改缩放中心点就全隐藏了) viewhelper.setpivotx(mcontent,0); viewhelper.setpivoty(mcontent,mcontent.getheight()/2); viewhelper.setscalex(mcontent,rightscale); viewhelper.setscaley(mcontent,rightscale); }
更多学习内容,可以点击《android侧滑效果汇总》学习。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。