1.Scroller到底是什么?

答:Scroller只是个计算器,提供插值计算,让滚动过程具有动画属性,但它并不是View,只是单纯地为滑动提供计算。

2.Scroller只是提供计算,那谁来让ViewGroup滑动

答:真正让ViewGroup滑动的是scrollTo,scrollBy 方法。Scroller 的 computeScrollOffset()方法的作用是计算ViewGroup 在当前时间点应该滑动到哪个位置。

在这里我想说一下,Scroller 的使用流程,首先,你创建一个scroller,然后你在computerScroll()方法 里面调用scroller 去计算当前应该滚动到的坐标位置。然后scrollTo 去使view滚动。

Scroller 使用

1.创建Scroller

        mScroller = new Scroller(context);

2.在onTouchEvent 方法里面调用mScroller fling 方法,开始快速滚动

case MotionEvent.ACTION_UP:mVelocityTracker.computeCurrentVelocity(1000,mScaledMaximumFlingVelocity);int yVelocity = (int) mVelocityTracker.getYVelocity();if (Math.abs(yVelocity) > mScaledMinimumFlingVelocity) {if (!mScroller.isFinished()) {mScroller.abortAnimation();}mScroller.fling(0,getScrollY(),0, -yVelocity,0,0,0,getLayout().getHeight() - getHeight());//之前老是掉帧的感觉   原来是因为fling 之后 并没有去执行invalidate 有时候可以是因为可能刚好到了60帧刷新的节点postInvalidateOnAnimation();}

3.在View 的 computeScroll 方法里面实现View 的Scroll

    @Overridepublic void computeScroll() {super.computeScroll();if (mScroller.computeScrollOffset()) {scrollBy(mScroller.getCurrX() - getScrollX() ,mScroller.getCurrY() - getScrollY());Log.d("ScrollTextView", "computescorll");}

注意:computerScroll 方法 会在 View 的 onDraw() 方法里面调用

下面是一个内容过长可以滚动的TextView:

package com.example.widget;import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import android.widget.OverScroller;
import android.widget.Scroller;import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import androidx.core.view.ViewConfigurationCompat;/*** =======================================================================================* 作    者:caoxinyu* 创建日期:2020/5/10.* 类的作用:可以上下滑动的TextView* 修订历史:*** 问题1.textView 高度有问题* 终于知道MeasureSpec.UNSPECIFIED 有什么用了* 因为有些是无限大的 比如 listView* 所以 他的尺寸应该是UNSPECIFIED 的* =======================================================================================*/
public class ScrollTextView extends androidx.appcompat.widget.AppCompatTextView {private Scroller mScroller;private OverScroller mOverScroller;private int mLastY;private VelocityTracker mVelocityTracker;private ViewConfiguration mViewConfiguration;private int mScaledMaximumFlingVelocity;private int mScaledMinimumFlingVelocity;private static final String TAG = "ScrollTextView";public ScrollTextView(Context context) {super(context);init(context);}public ScrollTextView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);init(context);}public ScrollTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(context);}private void init(Context context) {mScroller = new Scroller(context);mOverScroller = new OverScroller(context);mViewConfiguration = ViewConfiguration.get(context);mScaledMinimumFlingVelocity = mViewConfiguration.getScaledMinimumFlingVelocity();mScaledMaximumFlingVelocity = mViewConfiguration.getScaledMaximumFlingVelocity();Log.d("ScrollTextView", "mScaledMinimumFlingVelocity:" + mScaledMinimumFlingVelocity);Log.d("ScrollTextView", "mScaledMaximumFlingVelocity:" + mScaledMaximumFlingVelocity);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);}@Overridepublic boolean onTouchEvent(MotionEvent event) {if (mVelocityTracker == null) {mVelocityTracker = VelocityTracker.obtain();}switch (event.getAction()) {case MotionEvent.ACTION_DOWN:if (!mScroller.isFinished()) {mScroller.abortAnimation();}mLastY = (int) event.getY();break;case MotionEvent.ACTION_UP:mVelocityTracker.computeCurrentVelocity(1000,mScaledMaximumFlingVelocity);int yVelocity = (int) mVelocityTracker.getYVelocity();Log.d("ScrollTextView", "yVelocity:" + yVelocity);if (Math.abs(yVelocity) > mScaledMinimumFlingVelocity) {if (!mScroller.isFinished()) {mScroller.abortAnimation();}mScroller.fling(0,getScrollY(),0, -yVelocity,0,0,0,getLayout().getHeight() - getHeight());//之前老是掉帧的感觉   原来是因为fling 之后 并没有去执行invalidate 有时候可以是因为可能刚好到了60帧刷新的节点postInvalidateOnAnimation();}mVelocityTracker.recycle();mVelocityTracker = null;mLastY = (int) event.getY();break;case MotionEvent.ACTION_MOVE:boolean b = overScrollBy(0, (int) (mLastY - event.getY()), getScrollX(), getScrollY(), 0, getLayout().getHeight() - getHeight(), 0, 0, true);if (b) {mVelocityTracker.clear();}mLastY = (int) event.getY();break;}if (mVelocityTracker != null) {mVelocityTracker.addMovement(event);}return true;}@Overrideprotected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);if (!mScroller.isFinished()) {if (clampedY) {
//                mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange());}}else {super.scrollTo(scrollX, scrollY);Log.d("ScrollTextView", "onOverScrolled");}}@Overridepublic void computeScroll() {super.computeScroll();if (mScroller.computeScrollOffset()) {scrollBy(mScroller.getCurrX() - getScrollX() ,mScroller.getCurrY() - getScrollY());Log.d("ScrollTextView", "computescorll");}if (mOverScroller.computeScrollOffset()) {scrollTo(mOverScroller.getCurrX(),mOverScroller.getCurrY());}}/**** @param startx* @param starty* @param xDistance* @param yDistance* @param time*///如果time 很大,那么你的距离要相应的大 不然可能不会滑动public void startScroll(int startx,int starty,int xDistance,int yDistance,int time ){//startScroll 要调用invalidate 请求重新绘制mScroller.startScroll(startx,starty,xDistance,yDistance,time);invalidate();}public void startScroll(int startx,int starty,int xDistance,int yDistance){//startScroll 要调用invalidate 请求重新绘制
//        mScroller.startScroll(startx,starty,xDistance,yDistance);mOverScroller.startScroll(startx,starty,xDistance,yDistance);ViewCompat.postInvalidateOnAnimation(this);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);}
}

加油,慢慢积累,万物始于简单。one day,i will be 大神。

参考:http://www.linuxidc.com/Linux/2016-01/127276.htm

Android Scroller 使用详解相关推荐

  1. 《Android游戏开发详解》——第1章,第1.6节函数(在Java中称为“方法”更好)...

    本节书摘来自异步社区<Android游戏开发详解>一书中的第1章,第1.6节函数(在Java中称为"方法"更好),作者 [美]Jonathan S. Harbour,更 ...

  2. JMessage Android 端开发详解

    JMessage Android 端开发详解 目前越来越多的应用会需要集成即时通讯功能,这里就为大家详细讲一下如何通过集成 JMessage 来为你的 App 增加即时通讯功能. 首先,一个最基础的 ...

  3. 《Java和Android开发实战详解》——2.5节良好的Java程序代码编写风格

    本节书摘来自异步社区<Java和Android开发实战详解>一书中的第2章,第2.5节良好的Java程序代码编写风格,作者 陈会安,更多章节内容可以访问云栖社区"异步社区&quo ...

  4. Android事件流程详解

    Android事件流程详解 网络上有不少博客讲述了android的事件分发机制和处理流程机制,但是看过千遍,总还是觉得有些迷迷糊糊,因此特地抽出一天事件来亲测下,向像我一样的广大入门程序员详细讲述an ...

  5. Android Studio 插件开发详解二:工具类

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/78112856 本文出自[赵彦军的博客] 在插件开发过程中,我们按照开发一个正式的项 ...

  6. 《Android游戏开发详解》一2.16 区分类和对象

    本节书摘来异步社区<Android游戏开发详解>一书中的第2章,第2.16节,作者: [美]Jonathan S. Harbour 译者: 李强 责编: 陈冀康,更多章节内容可以访问云栖社 ...

  7. Android Framework系统服务详解

    Android Framework系统服务详解 操作环境 系统:Linux (Ubuntu 12.04) 平台:高通 Android版本:5.1 PS: 符号...为省略N条代码 一.大致原理分析 A ...

  8. android屏幕适配详解

    android屏幕适配详解 官方地址:http://developer.android.com/guide/practices/screens_support.html 一.关于布局适配建议 1.不要 ...

  9. Android LiveData组件详解以及LiveDataBus

    转载请标明出处:https://blog.csdn.net/zhaoyanjun6/article/details/99749323 本文出自[赵彦军的博客] 一.LiveData简介 LiveDat ...

最新文章

  1. C/C++左值性精髓(二)哪些表达式是左值,哪些是右值?----右值表达式
  2. P1197-星球大战【并查集,图论】
  3. 前端学习(3247):react的生命周期getSnapBeforeUpdate举例
  4. 通俗理解Java中的Lambda表达式
  5. eBPF BCC 实现UNIX socket抓包
  6. ActiveMQ使用线程池实现消息的生产与消费
  7. 【备战春招/秋招系列】美团Java面经总结进阶篇 (附详解答案) 1
  8. 唐宇迪机器学习笔记5:K近邻算法实战
  9. 基于Python的RNN文本生成写诗系统
  10. vs2010 solidworks2015 c# add-in模板 二次开发
  11. 光明顶短信支付:格式详解
  12. jmeterhttp代理服务器_Jmeter使用HTTP代理服务器录制脚本
  13. A problem occurred configuring project ‘:app‘.
  14. 全国程序员【工资统计】, 你想去哪个城市工作?
  15. html如何添加时钟效果,HTML5实现时钟效果
  16. 信号完整性设计的五个问题
  17. Python之Email邮箱账号抓取
  18. java的stackoverflow_call stack - 导致java.lang.StackOverflow的原因
  19. 【迭代式开发】v1架构设计文档——大数据开发实战项目(三)
  20. TLE82453使用

热门文章

  1. 计算机在线作业题,中医大计算机在线作业及答案-20210412090026.docx-原创力文档
  2. 实现断网收银_便利店收银系统,可以实现简单又好用!
  3. html2canvas 截图div_浏览器端网页截图方案详解
  4. vim配置python开发环境_VIM插件管理及python开发环境配置
  5. adb cannot connect to daemon_手机触屏失效的抢救办法,以及如何利用adb实现PC与手机交互...
  6. 如何获取微信openId
  7. 第55件事 产品疯传的7个基本原则
  8. Nginx-场景实践篇
  9. 市场与需求带动 向智能安放转型成大势所趋
  10. 《Groovy语言规范》-语法