好了,昨天已经实现了高仿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側滑菜单之滑动优化(二)的更多相关文章

  1. 高仿QQ6.0之側滑删除

    前两天已经完毕了高仿QQ6.0側滑和优化,今天来看下側滑删除的实现吧,假设有兴趣,能够去看下之前的两篇,仿QQ6.0側滑之ViewDragHelper的使用(一)和高仿QQ6.0側滑菜单之滑动优化(二 ...

  2. Android-通过SlidingMenu高仿微信6.2最新版手势滑动返回(二)

    转载请标明出处: http://blog.csdn.net/hanhailong726188/article/details/46453627 本文出自:[海龙的博客] 一.概述 在上一篇博文中,博文 ...

  3. Android 实现形态各异的双向側滑菜单 自己定义控件来袭

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/39670935.本文出自:[张鸿洋的博客] 1.概述 关于自己定义控件側滑已经写了 ...

  4. android:QQ多种側滑菜单的实现

    在这篇文章中写了 自己定义HorizontalScrollView实现qq側滑菜单 然而这个菜单效果仅仅是普通的側拉效果 我们还能够实现抽屉式側滑菜单 就像这样 第一种效果 另外一种效果 第三种效果 ...

  5. Android 高仿QQ5.2双向側滑菜单DrawerLayout实现源代码

    Android 高仿QQ5.2双向側滑菜单DrawerLayout实现源代码 左右側滑效果图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a ...

  6. Android 使用DrawerLayout高速实现側滑菜单

    一.概述 DrawerLayout是一个能够方便的实现Android側滑菜单的组件,我近期开发的项目中也有一个側滑菜单的功能.于是DrawerLayout就派上用场了.假设你从未使用过DrawerLa ...

  7. Android DrawerLayout 高仿QQ5.2双向侧滑菜单

    1.概述 之前写了一个Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭 ,恰逢QQ5.2又加了一个右侧菜单,刚好看了下DrawerLayout,一方面官方的东西,我都比较感兴趣:另一方面 ...

  8. iOS分组通讯录效果+側滑菜单(MMDrawerController)

    前言的废话-能够忽略 自从学会了使用Cocoapod,就欲罢不能了!由于太简单太赞了,不用再把源代码粘到project里了! 參见戴维营博客中的解说:Cocoapod 安装以及使用 先上一下效果图,请 ...

  9. 自己实现android側滑菜单

    当今的android应用设计中.一种主流的设计方式就是会拥有一个側滑菜单,以图为证:     实现这种側滑效果,在5.0曾经我们用的最多的就是SlidingMenu这个开源框架,而5.0之后.goog ...

随机推荐

  1. loj2021 「HNOI2017」大佬

    there #include <algorithm> #include <iostream> #include <cstring> #include <cst ...

  2. 链表中倒数第k个结点 【微软面试100题 第十三题】

    题目要求: 输入一个链表,输出该链表中倒数第k个结点.链表的倒数第0个结点为链表的尾指针. 参考资料:剑指offer第15题 题目分析: 1.两个指针,第一个先走k步,然后两个指针同时走,直到第一个走 ...

  3. 2.新手必须掌握的Linux命令

    第2章 新手必须掌握的Linux命令 章节简述: 本章首先介绍系统内核和Shell终端的关系与作用,然后介绍Bash解释器的4大优势并学习Linux命令的执行方法.经验丰富的运维人员可以通过合理地组合 ...

  4. MFC拾遗

    c++处理文件,对txt进行处理,学了那么久才发现我还不会这些操作,另外c++处理文本真是快得可怕啊 #include <iostream> #include <fstream> ...

  5. [转]如何把嵌套的python list转成一个一维的python list?

    import itertools a = [[1,2,3],[4,5,6], [7], [8,9]] out = list(itertools.chain.from_iterable(a))

  6. Spring 依赖注入(二、注入参数)

    注入参数基本分7类: 1.基本类型值 2.注入bean 3.内部bean 4.注入null值 5.级联属性 6.List,Set,Map集合的注入 7.properties文件的注入(和集合注入基本是 ...

  7. C++调用有道翻译API实现在线翻译之发声篇

    大概半月前写了一篇博文:C++中使用Curl和JsonCpp调用有道翻译API实现在线翻译, 得到大家的热情捧场,有人看了文章说要是能发声不是更好,我觉得说的也是哈,能听到专家的标准发音,那该是多美的 ...

  8. 【Luogu】P1419寻找段落(单调队列)

    题目链接 不知为何状态突然奇差无比,按说这题本来应该是水题的,但不仅不会做,还比着题解爆零五次 二分平均值(想到了),单调队列维护最大区间和(想到了但是不会,???为什么我不会???) #includ ...

  9. 【Luogu】P2146软件包管理器(树链剖分)

    题目链接 上午跟rqy学了一道超难的概率题,准备颓一会,于是水了这么一道水题. 话说这题真的是模板啊.数据范围正好,描述特别贴近(都不给你绕弯子的),连图都给你画出来,就差题目描述加一句“树链剖分模板 ...

  10. HDU 5402 : Travelling Salesman Problem

    题目大意:n*m的格子,从左上角走到右下角,每个格子只能走一遍,每个格子上有一个非负数,要让途径的数字和最大,最后要输出路径 思路:显然茹果n,m有一个是奇数的话所有格子的数字都能被我吃到,如果都是偶 ...