关闭

Scroller使用分析

701人阅读 评论(0) 收藏 举报
分类:

一.Scroller是什么?

  • Android里Scroller类是为了实现View平滑滚动的一个Helper类。通常在自定义的View时使用,在View中定义一个私有成员mScroller = new Scroller(context)。设置mScroller滚动的位置时,并不会导致View的滚动,通常是用mScroller记录/计算View滚动的位置,再重写View的computeScroll(),完成实际的滚动。

  • Scroller只是个计算器,提供插值计算,让滚动过程具有动画属性,但它并不是UI,也不是辅助UI滑动,反而是单纯地为滑动提供计算。

  • 无论从构造方法还是其他方法,以及Scroller的属性可知,其并不会持有View,辅助ViewGroup滑动。

  • Scroller只是提供计算,那谁来调用computeScroll使得ViewGroup滑动

  • computeScroll也不是来让ViewGroup滑动的,真正让ViewGroup滑动的是scrollTo,scrollBy。computeScroll的作用是计算ViewGroup如何滑动。而computeScroll是通过draw来调用的。

  • computeScroll和Scroller都是计算,两者有啥关系?没有直接的关系。computeScroll和Scroller要是飞得拉关系的话,那就是computeScroll可以参考Scroller计算结果来影响scrollTo,scrollBy,从而使得滑动发生改变。也就是Scroller不会调用computeScroll,反而是computeScroll调用Scroller。

  • 滑动时连续的,如何让Scroller的计算也是连续的?这个就问到了什么时候调用computeScroll了,如上所说computeScroll调用Scroller,只要computeScroll调用连续,Scroller也会连续,实质上computeScroll的连续性又invalidate方法控制,scrollTo,scrollBy都会调用invalidate,而invalidate回去触发draw,从而computeScroll被连续调用,综上,Scroller也会被连续调用,除非invalidate停止调用。

  • computeScroll如何和Scroller的调用过程保持一致?computeScroll参考Scroller影响scrollTo,scrollBy,实质上,为了不重复影响scrollTo,scrollBy,那么Scroller必须终止计算currX,currY。要知道计算有没有终止,需要通过mScroller.computeScrollOffset()

二.这个知识应用场景是?可以解决什么问题?

  我们在需求实现时,经常遇到view滑动的情况,而scrollTo、scrollBy方法都可以实现view的滑动,但是效果是瞬间完成的,用户体验并不好,我们可以使用scroller或者smoothScrollto(内部也是scroller实现的)来实现平滑移动的效果。常见于自定义view中。

三.该类的常见API?

mScroller.getCurrX() //获取mScroller当前水平滚动的位置  
mScroller.getCurrY() //获取mScroller当前竖直滚动的位置  
mScroller.getFinalX() //获取mScroller最终停止的水平位置  
mScroller.getFinalY() //获取mScroller最终停止的竖直位置  
mScroller.setFinalX(int newX) //设置mScroller最终停留的水平位置,没有动画效果,直接跳到目标位置  
mScroller.setFinalY(int newY) //设置mScroller最终停留的竖直位置,没有动画效果,直接跳到目标位置  

//滚动,startX, startY为开始滚动的位置,dx,dy为滚动的偏移量, duration为完成滚动的时间  
mScroller.startScroll(int startX, int startY, int dx, int dy) //使用默认完成时间250ms  
mScroller.startScroll(int startX, int startY, int dx, int dy, int duration)  

mScroller.computeScrollOffset() //返回值为boolean,true说明滚动尚未完成,false说明滚动已经完成。这是一个很重要的方法,通常放在View.computeScroll()中,用来判断是否滚动是否结束。  

四.常规的用法是什么?

  Scroller的基本用法其实还是比较简单的,主要可以分为以下几个步骤:
1. 创建Scroller的实例
2. 调用startScroll()方法来初始化滚动数据并刷新界面
3. 重写computeScroll()方法,并在其内部完成平滑滚动的逻辑

五.使用时的难点在哪里?

  使用的难点在于startScroll的参数含义,然后根据参数含义给出合适的值,因为这个过程涉及android中坐标计算,所以较为复杂。

         // void android.widget.Scroller.startScroll(int startX, int startY, int dx, int dy, int duration)
        // 第一个参数是起始移动的x坐标值,
        // 第二个是起始移动的y坐标值,
        // 第三个第四个参数都是移到某点的坐标值-初始的坐标值,即移动的距离值
        // 而duration 当然就是执行移动的时间。

六.一个案例:来自《android群英传》

public class ScrollerDragView extends View {
    private Scroller mScroller;
    private int mLastX;
    private int mLastY;

    public ScrollerDragView(Context context) {
        super(context);
        initView(context);
    }


    public ScrollerDragView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }

    private void initView(Context context) {
        setBackgroundColor(Color.BLUE);
        mScroller = new Scroller(context);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mLastX = (int) event.getX();
                mLastY = (int) event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                int offsetX = x - mLastX;
                int offsetY = y - mLastY;
                // 貌似使用了getParent,就不再需要重置x,y的坐标了
                ((View)getParent()).scrollBy(-offsetX, -offsetY);
                break;
            case MotionEvent.ACTION_UP:
                View viewGroup = (View) getParent();
                mScroller.startScroll(viewGroup.getScrollX(),
                        viewGroup.getScrollY(),
                        -viewGroup.getScrollX(),
                        -viewGroup.getScrollY());
                invalidate();
                break;
        }
        return true;
    }

    /**
     * 这里不需要特别的理解,只要使用Scroller,这里都是一样的
     */
    @Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.computeScrollOffset()) {
            ((View)getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
            invalidate();
        }
    }
}
0
0
查看评论

Android Scroller使用详解

转载请标明出处:http://blog.csdn.net/h_zhang/article/details/51045045仔细算一下,学习android开发已经有一年时间了。大概就是读了两本书以及看一些牛人牛博。我自认为我的语言组织以及表达能力是相当差的,有很多时候自己想明白的东西就是说不出来。所以...
  • H_Zhang
  • H_Zhang
  • 2016-04-02 19:09
  • 846

使用Scroller实现弹性滑动

scrollerTo、scrollBy View内部为了实现滑动提供了这两个方法,但是使用这两个方法滑动的效果是瞬间的不够平滑,如何实现View的弹性滑动呢?这正是本博文讨论的主题。另外这两个函数滑动的是View的内容不是View本身。比如对于普通View像TextView其内容就是文本,Image...
  • haohengyuan
  • haohengyuan
  • 2016-08-22 16:29
  • 2451

scroller类的用法完全解析以及带源码分析

通过上一篇内容对scrollTo与scrollBy用法以及TouchSlop与VelocityTracker解析后,接下来我们再来聊聊scroller类,首先最好要有上一篇内容作为基础(建议先看看上篇的内容),才能比较容易理解本篇内容。以下为本篇内容概要:       ...
  • javazejian
  • javazejian
  • 2016-01-21 17:38
  • 1747

Android View视图系统分析和Scroller和OverScroller分析

Android  View视图系统分析和Scroller和OverScroller分析 View  视图分析         首先,我们知道,在Android中所有的视图资源(不管是Layout还是View),最终的父类都是View...
  • jaysong2012
  • jaysong2012
  • 2015-07-15 13:53
  • 2813

解决ListView嵌套在ScrollerView中显示不全以及滑动冲突的问题

解决ListView嵌套在ScrollerView中显示不全以及滑动冲突的问题
  • u013398830
  • u013398830
  • 2015-09-06 17:30
  • 780

Scroller的应用--滑屏实现

1、Scroller源码分析下面是对Scroller源码的分析,并附有源码,如下:package android.widget; import android.content.Context; import android.hardware.SensorManager; import androi...
  • jwzhangjie
  • jwzhangjie
  • 2014-09-01 13:06
  • 7995

Scroller分析

1 2 3 4 5 6 7 8 9 10 11 12 mScroller.getCurrX() //获取mScroller当前水平滚动的位置 mScroller.getCurrY() //获...
  • pingqingbo
  • pingqingbo
  • 2015-10-23 10:26
  • 218

[Egret学习笔记 五]GUI Scroller的使用

直接上代码: 1.“bgImage” 配置在resource.json egret的背景图 { "name":"bgImage", "type":"image", "url":&...
  • rcjjian
  • rcjjian
  • 2015-04-10 11:51
  • 1956

Scroller使用分析和总结

一、概述 这个类封装了滚动操作。滚动的持续时间可以通过构造函数传递,并且可以指定滚动动作的持续的最长时间。经过这段时间,滚动会自动定位到最终位置,并且通过computeScrollOffset()会得到的返回值为false,表明滚动动作已经结束。 二、构造函函数 public Scroller...
  • wf_zeng
  • wf_zeng
  • 2013-07-16 14:08
  • 736

Scroller类的使用(用来在ViewGroup里面让子view经常优美 的滑动)

Scroller s=new Scroller(Context con); 这个类里面有一个scroller.startScroll(startX, startY, disX, disY, duration);这样的方法 第一个参数是要移动的初始位置X坐标的值, 第一个参数是要移动的初...
  • qq_15949077
  • qq_15949077
  • 2015-07-18 10:49
  • 339
    写给自己
    ○ 种一棵树最好的时间是十年前,其次是现在

    ○ 坚持输出,坚持书写,才可以持续成长

    ○ 所有美好事物的成长都是缓慢的

    ○ 既往不恋,未来不迎,当下不杂

    ○ 业精于勤,荒于嬉,行成于思,毁于随

    ○将军赶路 不追小兔

    ○不要拘泥于语言,同样也不要拘泥于行业,眼光放远一点

    ○ 如果某件事你做的不够好,不必介怀,因为以后的每一次每一天你都会做得越来越好

    ○ 此心不于事上磨,更于何处磨此心

    ○ 保持热情,保持求知欲

    ○ 千里之行,始于足下

    ○ 最怕你一生碌碌无为,还安慰自己平凡可贵。

    ○ 对于任何事,要保持自觉积极主动探索尝试。但是如果自己不积极认真地生活,不管得到什么样的回答都没有用。——解忧杂货店
    个人资料
    • 访问:697151次
    • 积分:7178
    • 等级:
    • 排名:第3760名
    • 原创:298篇
    • 转载:53篇
    • 译文:0篇
    • 评论:121条
    个人简介