项目中有个需求,就是在RecyclerView的item中进行侧滑,一开始同事推荐了一个开源库,使用起来确实也方便好用,直接在布局作为父布局即可实现侧滑。

自己也非常好奇这个开源库到底用了什么API能实现这种效果,于是慢慢开始了源码的阅读。


Scroller:

这个类是原生提供的滚动辅助工具类,使用它可以根据开始位置和结束位置计算出当前应该滚动到的坐标。

需要注意的是:Scroller并不会帮你设置View的滚动位置,它只负责计算当前应该滚动到的位置,所以你需要手动View的滚动位置。

下面是部分源码,当快速在Item进行手势侧滑,当手指抬起时,会使用Scroller进行计算。

case MotionEvent.ACTION_UP:
    // .....    mScroller.startScroll(startX, 0, endX - startX, 0, 400);   // ......     cancel();    break;
public void startScroll(int startX, int startY, int dx, int dy, int duration)调用此方法,将会开启计算滚动,在滚动计算启动后,你可以在任意时刻调用computeScrollOffset()让Scrooler计算最新位置。
public boolean computeScrollOffset()让Scrooler计算最新位置,此法返回布尔值,如果为真表示还没滚动到目标位置,否则表示已经滚动到目标位置。
public final int getCurrX()调用computeScrollOffset()之后,可以通过此方法获取当前应该滚动到x坐标,同理也有getCurrY()。
 

View.computeScroll()

在了解View.computeScroll()方法前,需要了解一下View.scrollTo()和View.scrollBy()方法。

scrollTo():将View滚动到指定位置。

scrollBy():内部其实是调用了scrollTo()方法。

public void scrollTo(int x, int y) {
    if (mScrollX != x || mScrollY != y) {
        int oldX = mScrollX;
        int oldY = mScrollY;
        mScrollX = x;
        mScrollY = y;
        invalidateParentCaches();
        onScrollChanged(mScrollX, mScrollY, oldX, oldY);
        if (!awakenScrollBars()) {
            postInvalidateOnAnimation();
        }
    }
}

public void scrollBy(int x, int y) {
    scrollTo(mScrollX + x, mScrollY + y);
}

这里讲解一下scrollTo()和scrollBy()方法的重要流程:scrollTo()  ==>  postInvalidateOnAnimation()  ==>  重绘  ==> View.computeScroll()

View.computeScroll()这个方法会在重绘的时候进行调用,而scrollTo()会触发重绘操作。在View里面,computeScroll()是一个空方法。

/**
 * Called by a parent to request that a child update its values for mScrollX
 * and mScrollY if necessary. This will typically be done if the child is
 * animating a scroll using a {@link android.widget.Scroller Scroller}
 * object.
 */
public void computeScroll() {

}

系统原生说得很明白了,在computeScroll()里面我们通常是使用Scroller进行计算滚动位置,然后执行动画滚动。

// 一个例子public void computeScroll() {
    // 如果还没有滚动到最后位置
    if(mScroller.computeScrollOffset()){        // scrollTo()和scrollBy()方法都是没有动画效果的,是瞬间就滚动了View,所以通过Scroller不断计算滚动进行细微滚动,形成滚动效果。
        scrollTo(mScroller.getCurrX() ,mScoller.getCurrY());
        postInvalidate();
    }
}
												

【安卓进阶】Scroller理解与应用的更多相关文章

  1. python 变量进阶(理解)

    变量进阶(理解) 目标 变量的引用 可变和不可变类型 局部变量和全局变量 01. 变量的引用 变量 和 数据 都是保存在 内存 中的 在 Python 中 函数 的 参数传递 以及 返回值 都是靠 引 ...

  2. 安卓进阶之自定义View

    目录 安卓进阶之自定义View 自定义View的工作流程和内容 工作流程 测量阶段和布局阶段的工作内容 View 和 ViewGroup 在测量阶段和布局阶段的区别 绘制阶段的工作内容 上手:实现继承 ...

  3. JavaScript 开发进阶:理解 JavaScript 作用域和作用域链

    作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理.今天这篇文章对JavaScript作用域和作用域链作简单的介绍,希望 ...

  4. JavaScript 开发进阶:理解 JavaScript 作用域和作用域链(转载 学习中。。。)

    作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理.今天这篇文章对JavaScript作用域和作用域链作简单的介绍,希望 ...

  5. 【安卓进阶】Product Flavor基础玩法

    在安卓项目开发中,大多时候总是有测试环境.生产环境之类的区别,在不使用Product Flavor时,我们一般都是通过手工改动代码来实现测试环境.生产环境的切换. 这样就造成了项目管理上的不便,频繁的 ...

  6. Understanding Android Security(安卓安全的理解)

    论文作者: Enck, William Ongtang, MacHigar McDaniel, Patrick 下一代的开放操作系统不会在个人主机和大型主机上出现,而是在只能手机上.新环境的开放性将会 ...

  7. 【安卓进阶】LiveData

    最近参与到后端的工作中,虽然以前在工作中使用过PHP,但是这次使用的是Java,开发思路和方式有所不同.后端开发中,做接口也是需要处理大量的业务逻辑关系,同时一些事务之类的技术因素也要考虑好,在架设项 ...

  8. 安卓中的消息循环机制Handler及Looper详解

    我们知道安卓中的UI线程不是线程安全的,我们不能在UI线程中进行耗时操作,通常我们的做法是开启一个子线程在子线程中处理耗时操作,但是安卓规定不允许在子线程中进行UI的更新操作,通常我们会通过Handl ...

  9. Java都有什么进阶技术

    Java都有什么进阶技术?   看到有人给题主推荐<代码整洁之道>,评论有人说那不是JAVA进阶的书- 私以为,一些人对JAVA进阶的理解片面了,JAVA不过也是一门语言,提升和进阶还是内 ...

随机推荐

  1. Kali Hydra SSL issue, xHydra (GUI version of Hydra) works just fine

    First find the source code. (https://is.gd/LlS5Sy) - Example search Once located you must download i ...

  2. vue中使用vue-quill-editor及上传图片到自己服务器

    第一步,下载依赖 cnpm install vue-quill-editor --save 第二步,再main.js里引入组件(我这里是全局注册) // 富文本编辑器 import VueQuillE ...

  3. egg.js异步请求数据

    之前已经简单的使用egg-init初始化项目,并创建控制器controller和服务service 在实际项目中, service主要负责数据的请求,并处理(http请求) controll主要负责获 ...

  4. unity组件路径自动生成

    unity 有时候找路径太麻烦 写了一个自动生成脚本的工具 using System.Collections.Generic; using System.IO; using System.Text; ...

  5. php中双$符 及一些基础知识

    双$$符号表示可变变量 如 $a = "b", $b = 'c'; echo $$a    此时 $$a=>$($a) =>$b 输出的值就应该为c; 变量传应用值$b ...

  6. 迷宫问题 (bfs广度优先搜索记录路径)

    问题描述: 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, ...

  7. hdu1693 插头dp

    题意:给了一个矩阵图,要求使用回路把图中的树全部吃掉的方案树,没有树的点不能走,吃完了这个点也就没有了,走到哪吃到哪 用插头dp搞 #include <iostream> #include ...

  8. 数据库表中不建索引,在插入数据时,通过sql语句防止重复添加

    sql 语句 INSERT IGNORE INTO table(aaa,bbb) SELECT '1111','2222' FROM DUAL WHERE NOT EXISTS( ' ) mybati ...

  9. wpf中插入winform控件并获取句柄

    因工作需要使用wpf做界面,而有个开发包依赖picturebox控件,上网研究了一下,总算弄通了. 首先在项目中添加引用System.Windows.Forms与WindowsFormsIntegra ...

  10. 在java中实现数据导入excel表格中

    1.首先前端代码如下: 一个导出按钮:<input id="export" class="btn btn-primary" type="butt ...