高仿QQ6.0側滑菜单之滑动优化(二)
好了,昨天已经实现了高仿QQ6.0的側滑大致框架。如有兴趣。能够去看下仿QQ6.0側滑之ViewDragHelper的使用(一)
可是之前的实现。仅仅是简单的能够显示和隐藏左側的菜单,可是特别生硬,并且没有不论什么平滑的趋势,那么今天就来优化一下吧,加上平滑效果,并且能够依据手势滑动的方向来推断是否是显示和隐藏。
首先先来实现手势推断是否隐藏和显示
这里就要用到了一个方法了,例如以下:
这个是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的方法,留给外面的调用吧。。代码非常easy:
/**
* 定义当前状态 默认是关闭状态
*/
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的地址,后期加入的也会更新至此。
本项目的github地址:https://github.com/wuyinlei/QQ6.0
如有问题。或者交流的话,能够QQ:1069584784。
高仿QQ6.0側滑菜单之滑动优化(二)的更多相关文章
- 高仿QQ6.0之側滑删除
前两天已经完毕了高仿QQ6.0側滑和优化,今天来看下側滑删除的实现吧,假设有兴趣,能够去看下之前的两篇,仿QQ6.0側滑之ViewDragHelper的使用(一)和高仿QQ6.0側滑菜单之滑动优化(二 ...
- Android-通过SlidingMenu高仿微信6.2最新版手势滑动返回(二)
转载请标明出处: http://blog.csdn.net/hanhailong726188/article/details/46453627 本文出自:[海龙的博客] 一.概述 在上一篇博文中,博文 ...
- Android 实现形态各异的双向側滑菜单 自己定义控件来袭
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39670935.本文出自:[张鸿洋的博客] 1.概述 关于自己定义控件側滑已经写了 ...
- android:QQ多种側滑菜单的实现
在这篇文章中写了 自己定义HorizontalScrollView实现qq側滑菜单 然而这个菜单效果仅仅是普通的側拉效果 我们还能够实现抽屉式側滑菜单 就像这样 第一种效果 另外一种效果 第三种效果 ...
- Android 高仿QQ5.2双向側滑菜单DrawerLayout实现源代码
Android 高仿QQ5.2双向側滑菜单DrawerLayout实现源代码 左右側滑效果图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a ...
- Android 使用DrawerLayout高速实现側滑菜单
一.概述 DrawerLayout是一个能够方便的实现Android側滑菜单的组件,我近期开发的项目中也有一个側滑菜单的功能.于是DrawerLayout就派上用场了.假设你从未使用过DrawerLa ...
- Android DrawerLayout 高仿QQ5.2双向侧滑菜单
1.概述 之前写了一个Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭 ,恰逢QQ5.2又加了一个右侧菜单,刚好看了下DrawerLayout,一方面官方的东西,我都比较感兴趣:另一方面 ...
- iOS分组通讯录效果+側滑菜单(MMDrawerController)
前言的废话-能够忽略 自从学会了使用Cocoapod,就欲罢不能了!由于太简单太赞了,不用再把源代码粘到project里了! 參见戴维营博客中的解说:Cocoapod 安装以及使用 先上一下效果图,请 ...
- 自己实现android側滑菜单
当今的android应用设计中.一种主流的设计方式就是会拥有一个側滑菜单,以图为证: 实现这种側滑效果,在5.0曾经我们用的最多的就是SlidingMenu这个开源框架,而5.0之后.goog ...
随机推荐
- canvas 动画库 CreateJs 之 EaselJS(下篇)
本文来自网易云社区 作者:田亚楠 继承 对应原文:Inheritance 我们可以继承已有的「显示对象」,创建新的自定义类.实现方法有很多种,下面介绍其中之一. 举例:实现一个继承于 Containe ...
- Linux IP怎么设置
最常用的给网卡配置ip的命令为#ifconfig eth0 192.168.0.1 但是,这样重启后又打回原形.要想永久保存,需要 vim /etc/sysconfig/network-scripts ...
- Nginx从入门到放弃-第2章 基础篇
2-1 什么是Nginx 2-2 常见的中间件服务 2-3 Nginx的特性_实现优点1 2-4 Nginx特性_实现优点2 2-5 Nginx特性_实现优点3 2-6 Nginx特性_实现优点4 2 ...
- python学习-- 两种方式查看自己的Django版本
[第一种方式] Windows系统下 按住Windows按键 + R 进入搜索:搜索CMD进入控制台:输入Python进入Python解释器 Linux系统下 直接使用终端调用Python解释器 接下 ...
- 紫书第一章训练1 D -Message Decoding
Some message encoding schemes require that an encoded message be sent in two parts. The first part, c ...
- Git只获取部分目录的内容
Git只获取部分目录的内容 Git的克隆,默认是直接拉取整个远程仓库,如果项目比较大,大量和自己无关的内容也会拉到本地,占用很多硬盘空间.Git在1.7版本后,已经支持只Checkout部分内容,这个 ...
- OpenCV For Java环境搭建与功能演示
http://blog.csdn.net/jia20003/article/details/68944486
- 网络编程之IO复用:select or epoll
对于服务器的并发处理能力,我们需要的是:每一毫秒服务器都能及时处理这一毫秒内收到的数百个不同TCP连接上的报文,与此同时,可能服务器上还有数以十万计的最近几秒没有收发任何报文的相对不活跃连接.同时处理 ...
- ACM程序设计选修课——1030: Hungar的时尚球场(水题+耐心)
1030: Hungar的时尚球场 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 14 Solved: 8 [Submit][Status][Web ...
- linux 程序自动运行总结
1.开机启动时自动运行程序Linux加载后, 它将初始化硬件和设备驱动, 然后运行第一个进程init.init根据配置文件继续引导过程,启动其它进程.通常情况下,修改放置在 /etc/rc或 /etc ...