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

 更新时间:2016年02月04日 11:52:42   作者:若兰明月  
之前的实现只是简单的可以显示和隐藏左侧的菜单,但是特别生硬,而且没有任何平滑的趋势,那么今天就来优化一下吧,加上平滑效果,而且可以根据手势滑动的方向来判断是否是显示和隐藏

 推荐阅读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);
}

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

这里写图片描述

这个时候,基本上差不多了,剩下的,我们就来添加一些状态和设置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侧滑基本完成,下面我们来看下效果吧。

这里写图片描述 

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

相关文章

  • Android开发之天气趋势折线图

    Android开发之天气趋势折线图

    在开发天气APP的时候会要显示多天的信息,所以加一个折线图来显示一下天气变化趋势是很不错的效果,本文详细介绍了开发过程,下面一起来看看。
    2016-08-08
  • android使用 ScrollerView 实现 可上下滚动的分类栏实例

    android使用 ScrollerView 实现 可上下滚动的分类栏实例

    本篇文章主要介绍了android使用 ScrollerView 实现 可上下滚动的分类栏实例,具有一定的参考价值,有兴趣的可以了解一下。
    2017-01-01
  • Android中播放在线音乐代码

    Android中播放在线音乐代码

    这篇文章主要介绍了Android中播放在线音乐代码,本文只给出了核心操作代码,需要的朋友可以参考下
    2015-04-04
  • 简单谈谈android studio 的单元测试

    简单谈谈android studio 的单元测试

    昨天在完善项目的时候,需要进行单元测试,在Eclipse环境中进行是很简单的,但是在Android Studio环境中进行单元测试,在国内找了很多资料,大都是人云亦云,本文发布出来供大家学习参考。
    2016-08-08
  • Android学习之使用SharedPreferences存储应用程序数据

    Android学习之使用SharedPreferences存储应用程序数据

    这篇文章主要为大家详细介绍了Android学习之使用SharedPreferences保存应用程序数据的相关资料,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • Android使用Retrofit上传文件功能

    Android使用Retrofit上传文件功能

    这篇文章主要为大家详细介绍了Android使用Retrofit上传文件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • Android与iOS包体优化及一键自动打包脚本

    Android与iOS包体优化及一键自动打包脚本

    这篇文章主要为大家介绍了安卓与iOS包体优化及一键自动打包脚本详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • Android Studio用genymotion运行后小图标无法显示问题

    Android Studio用genymotion运行后小图标无法显示问题

    这篇文章主要介绍了Android Studio用genymotion运行后小图标无法显示的问题,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • Android实现侦听电池状态显示、电量及充电动态显示的方法

    Android实现侦听电池状态显示、电量及充电动态显示的方法

    这篇文章主要介绍了Android实现侦听电池状态显示、电量及充电动态显示的方法,非常实用的功能,需要的朋友可以参考下
    2014-09-09
  • Qt5.12.6配置Android Arm开发环境(图文)

    Qt5.12.6配置Android Arm开发环境(图文)

    本文主要介绍了Qt5.12.6配置Android Arm开发环境,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06

最新评论