Scroller简介

来源:互联网 发布:mysql数据库安全方案 编辑:程序博客网 时间:2024/06/16 02:24

之前说的scrollTo和scrollBy确实可以实现View的滚动,但我们要想让View像我们常见的ViewPager那样平滑的滚动,只用这两方法是做不多的,因为它们产生的滚动是不连贯的,闪烁的,所以系统也为我们提供了Scroller这个类来实现View的平滑滚动

Scroller典型用法

Scroller mScroller = new Scroller(mContext);private void smoothScroll(int destX, int destY) {        int scrollX = getScrollX();        int deltaX = destX - scrollX;        mScroller.startScroll(scrollX, 0, deltaX, 0, 500);        invalidate();    }@Override    public void computeScroll() {        super.computeScroll();        if (mScroller.computeScrollOffset()) {            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());            invalidate();        }    }

根据上面的代码可把Scroller的使用概括为以下五个主要步骤

  1. 初始化Scroller
  2. 调用startScroll()开始滚动
  3. 执行invalidate()刷新界面
  4. 重写View的computeScroll()并在其内部实现与滚动相关的业务逻辑
  5. 再次执行invalidate()刷新界面

我们知道手机屏幕左上角为原点(0,0)

创建一些子View的时候,就会有一些超过屏幕的区域,可正可负,如图所示
原理图

getScrollX():屏幕原点X坐标减去调用视图左上角X坐标,例如蓝色图得到的为0-(-480)=480

getScrollY():屏幕原点Y坐标减去调用视图左上角Y坐标,例如蓝色图得到的为0-0=0

mScroller.startScroll(int startX,int startY,int dx,int dy)

startX:表示View X坐标滚动的开始位置;
startY:表示View Y坐标滚动的开始位置 
dx:表示View 从X坐标的开始位置需要滚动的距离(这里dx的正负是和ScrllTo() 的x一样的)
dy:表示View 从Y坐标开始位置需要滚动的距离(dy的正负和scrllTo的 y 一样的)

startScroll源码

/**   * Start scrolling by providing a starting point, the distance to travel,   * and the duration of the scroll.   *    * @param startX Starting horizontal scroll offset in pixels. Positive   *        numbers will scroll the content to the left.   * @param startY Starting vertical scroll offset in pixels. Positive numbers   *        will scroll the content up.   * @param dx Horizontal distance to travel. Positive numbers will scroll the   *        content to the left.   * @param dy Vertical distance to travel. Positive numbers will scroll the   *        content up.   * @param duration Duration of the scroll in milliseconds.   */  public void startScroll(int startX, int startY, int dx, int dy, int duration) {      mMode = SCROLL_MODE;      mFinished = false;      mDuration = duration;      mStartTime = AnimationUtils.currentAnimationTimeMillis();      mStartX = startX;      mStartY = startY;      mFinalX = startX + dx;      mFinalY = startY + dy;      mDeltaX = dx;      mDeltaY = dy;      mDurationReciprocal = 1.0f / (float) mDuration;  }

通过源码可以看到,当调用startScroll()时,内部并没有做什么滚动的操作,只是做了赋值的操作,所以当调用了这段代码之后,
我们需要调用invalidate()方法来让View重绘从而调用View里computeScroll()方法,在View源码里computeScroll()方法是个空实现,所以我们可以在这个方法里面做滚动的逻辑

例如:

public void computeScroll(){    if (mScroller.computeScrollOffset()) {        scrollTo(0, mScroller.getCurrY());        postInvalidate();    }    super.computeScroll();}

computeScroll()方法里,我们一般用mScroller.compuScrollOffset()来判断View的滚动是否在继续,返回true表示还在继续,false 表示结束

DEMO

这里写图片描述

Demo下载地址

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 qq被腾讯屏蔽了怎么办 电脑被u盘中毒怎么办 电脑一分钟重启怎么办 创维电视音量小怎么办 捷豹pin码忘记了怎么办 华为手机版本更新下载不了怎么办? 微信钱包没有钱怎么办 微信钱包里没有钱怎么办 微信没有收到退款怎么办 微信转账退款没有收到怎么办 礼物跟人家送重复怎么办 你已被steam封禁怎么办 武装突袭3被锁定怎么办 绝地求生右下角小地图变大怎么办 ctrl z 误删了怎么办 武装突袭3渴了怎么办 武装突袭3枪卡壳怎么办 玩武装突袭3CPU不好怎么办? 户户通001信号中断怎么办 电脑运行速度特别慢怎么办 win8.1电脑太卡怎么办 电线厂非法战地没拆够怎么办 久笔记本电脑玩彩虹六号卡怎么办 彩虹六号一直建立小队进不去怎么办 小佩喂食器离线怎么办 手机打游戏掉帧怎么办 电脑打游戏掉帧怎么办 武装突袭3太卡怎么办 英语b级考不过怎么办 绝地求生被燃烧瓶烧了怎么办 搜狗输入法打字出现问好怎么办 全民k歌解码失败怎么办 视频声音小怎么办调大 乐视2视频声音小怎么办 录视频声音太小怎么办 显卡装了没反应怎么办 笔记本关闭核显黑屏怎么办 驱动补丁被卸了怎么办 网络驱动被删了怎么办 新装系统网卡没驱动怎么办 核显没有dp口怎么办