欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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侧滑效果汇总》学习。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。