推荐阅读:Android使用ViewDragHelper实现仿QQ6.0侧滑界面(一)
但是之前的实现,只是简单的可以显示和隐藏左侧的菜单,但是特别生硬,而且没有任何平滑的趋势,那么今天就来优化一下吧,加上平滑效果,而且可以根据手势滑动的方向来判断是否是显示和隐藏。
首先先来实现手势判断是否隐藏和显示
这里就要用到了一个方法了,如下:
这个是ViewDradHelper里面的方法:
/*** 当view被释放的时候处理的事情(松手)** @param releasedChild 被释放的子view* @param xvel 水平方向的速度 帧每秒 向右为 +* @param yvel 竖直方向的速度 向下为 +*/@Overridepublic 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所在的viewgroupViewCompat.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所在的viewgroupViewCompat.postInvalidateOnAnimation(this);} else {mMainContent.layout(finalLeft, 0, finalLeft + mWidth, finalLeft + mHeight);}}public void open() {open(true);}
来看下效果图吧(里面的白道问题是录屏导致,运行的没有这个哈):
这个时候,基本上差不多了,剩下的,我们就来添加一些状态和设置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.0fLog.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侧滑基本完成,下面我们来看下效果吧。
好了,这个侧滑就这样完成了,后期会加在主页中加入listview(尝试用RecycleView)实现左滑删除效果,现在附上该demo的地址,后期添加的也会更新至此。
新闻热点
疑难解答
图片精选