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

Android滑动优化高仿QQ6.0侧滑菜单(滑动优化)

程序员文章站 2024-02-16 10:25:34
 推荐阅读:android使用viewdraghelper实现仿qq6.0侧滑界面(一) 但是之前的实现,只是简单的可以显示和隐藏左侧的菜单,但是特别生硬,而且...

 推荐阅读android使用viewdraghelper实现仿qq6.0侧滑界面(一)

但是之前的实现,只是简单的可以显示和隐藏左侧的菜单,但是特别生硬,而且没有任何平滑的趋势,那么今天就来优化一下吧,加上平滑效果,而且可以根据手势滑动的方向来判断是否是显示和隐藏。

首先先来实现手势判断是否隐藏和显示

这里就要用到了一个方法了,如下:

这个是viewdradhelper里面的方法:

/**
* 当view被释放的时候处理的事情(松手)
*
* @param releasedchild 被释放的子view
* @param xvel 水平方向的速度 帧每秒 向右为 +
* @param yvel 竖直方向的速度 向下为 +
*/
@override
public void onviewreleased(view releasedchild, float xvel, float yvel) {
log.d("draglayout", "xvel : " + xvel + " yvel :" + yvel);
super.onviewreleased(releasedchild, xvel, yvel);
//判断关闭和打开
//在这里我们首先判断什么时候打开,然后剩下的都是关闭状态
//首先是我的主面板的左侧具体屏幕左侧已经大于mrange/2的距离并且右滑的速度大于0,此时打开
if (xvel >= 0 && mmaincontent.getleft() > mrange / 2.0f) {
open();
} else if (xvel > 0) {
//第二种就是我右滑的速度大于0(这里的速度自己定义哈,根据自己想要实现的敏感度)
open();
} else {
//剩余的所有情况都是关闭
close();
}
}

close()方法(draglayout里面的方法):

/**
* 关闭
*/
public void close() {
int finalleft = 0;
//调用layout方法,摆放主布局
/**
* @param l left position, relative to parent
* @param t top position, relative to parent
* @param r right position, relative to parent
* @param b bottom position, relative to parent
*/
mmaincontent.layout(finalleft, 0, finalleft + mwidth, finalleft + mheight);
}

open()方法(draglayout里面的方法):

/**
* 打开
*/
public void open() {
int finalleft = mrange;
mmaincontent.layout(finalleft, 0, finalleft + mwidth, finalleft + mheight);
}

这个是否就可以实现根据手势来判断是否打开和关闭了。

接下来我们就来实现如何平滑的关闭和打开,话不多说,代码说话(这里对上面的open和close做了一些处理):

public void close() {
close(true);
}
/**
* 关闭
*
* @param issmooth 是否平滑的关闭
*/
public void close(boolean issmooth) {
int finalleft = 0;
if (issmooth) {
/**
* public boolean smoothslideviewto(view child, int finalleft, int finaltop)方法的解释
*
* animate the view <code>child</code> to the given (left, top) position.
* if this method returns true, the caller should invoke {@link #continuesettling(boolean)}
* on each subsequent frame to continue the motion until it returns false. if this method
* returns false there is no further work to do to complete the movement.
*
* 返回true 代表还没有移动到指定的位置,需要刷新界面,继续移动
* 返回false 就停止工作哈
*/
//1、触发动画
if (mdraghelper.smoothslideviewto(mmaincontent, finalleft, 0)) {
//参数传this,也就是child所在的viewgroup
viewcompat.postinvalidateonanimation(this);
}
} else {
//调用layout方法,摆放主布局
/**
* @param l left position, relative to parent
* @param t top position, relative to parent
* @param r right position, relative to parent
* @param b bottom position, relative to parent
*/
mmaincontent.layout(finalleft, 0, finalleft + mwidth, finalleft + mheight);
}
}
/**
* 打开
*/
public void open(boolean issmooth) {
int finalleft = mrange;
if (issmooth && mdraghelper.smoothslideviewto(mmaincontent, finalleft, 0)) {
//参数传this,也就是child所在的viewgroup
viewcompat.postinvalidateonanimation(this);
} else {
mmaincontent.layout(finalleft, 0, finalleft + mwidth, finalleft + mheight);
}
}
public void open() {
open(true);
}

来看下效果图吧(里面的白道问题是录屏导致,运行的没有这个哈):

Android滑动优化高仿QQ6.0侧滑菜单(滑动优化)

这个时候,基本上差不多了,剩下的,我们就来添加一些状态和设置listener的方法,留给外面的调用吧。,代码很简单:

/**
* 定义当前状态 默认是关闭状态
*/
private status mstatus = status.close;
/**
* 状态枚举
* 关闭 close
* 打开 open
* 拖拽 draging
*/
public enum status {
close, open, draging;
}
private ondragstatuslistener mlistener;
public void setdragstatelistener(ondragstatuslistener listener) {
mlistener = listener;
}
public interface ondragstatuslistener {
/**
* 关闭逻辑
*/
void onclose();
/**
* 打开逻辑
*/
void onopen();
/**
* 拖拽逻辑
*
* @param percent
*/
void ondraging(float percent);
}

状态更新,方法调用,这个dispatchdragevent()在onviewpositionchanged()这个方法中调用一下就行,因为拖拽的时候状态时刻在变化,所以我们在这个方法中调用:

/**
* 状态更新方法执行
* 
* @param newleft
*/
private void dispatchdragevent(int newleft) {
//得到的一个百分比
float percent = newleft * 1.0f / mrange;
//0.0f--->1.0f
log.d("draglayout", "percent : " + percent);
if (mlistener != null) {
mlistener.ondraging(percent);
}
//跟新状态执行回调
status laststatus = mstatus;
mstatus = updatestatus(percent);
if (mstatus != laststatus) {
//状态发生变化
if (mstatus == status.close) {
//当前状态是关闭
if (mlistener != null) {
mlistener.onclose();
}
} else if (mstatus == status.open) {
if (mlistener != null) {
mlistener.onopen();
}
}
}
}
/**
* 状态更新方法
*
* @param percent
* @return
*/
private status updatestatus(float percent) {
if (percent == 0) {
return status.close;
} else if (percent == 1) {
return status.open;
}
return status.draging;
}

好了,到此为止,高仿qq6.0侧滑基本完成,下面我们来看下效果吧。

Android滑动优化高仿QQ6.0侧滑菜单(滑动优化) 

好了,这个侧滑就这样完成了,后期会加在主页中加入listview(尝试用recycleview)实现左滑删除效果,现在附上该demo的地址,后期添加的也会更新至此。