Scorller的使用详解一

更多分享:http://www.cherylgood.cn

Scorller类官方介绍


  • This class encapsulates scrolling. You can use scrollers (Scroller or OverScroller) to collect the data you need to produce a scrolling animation—for example, in response to a fling gesture. Scrollers track scroll offsets for you over time, but they don't automatically apply those positions to your view. It's your responsibility to get and apply new coordinates at a rate that will make the scrolling animation look smooth.

  • 这个类封装了滚动。 你可以使用scrollers(可译为滚动起)(Scroller或OverScroller)收集你需要生成的滚动动画所需要的数据,例如响应一个甩动手势。 Scrollers随着时间的推移跟踪滚动的偏移量,但不会自动将这些位置设置给你的view。 你有责任按一定的频率去获取当前滚动的坐标并应用在你的view上以使滚动动画看起来很顺滑。
    示例代码:

    private Scroller mScroller = new Scroller(context);
    ...
    public void zoomIn() {
    // Revert any animation currently in progress
    mScroller.forceFinished(true);
    // Start scrolling by providing a starting point and
    // the distance to travel
    mScroller.startScroll(0, 0, 100, 0);
    // Invalidate to request a redraw
    invalidate();
    }

  • To track the changing positions of the x/y coordinates, use computeScrollOffset(). The method returns a boolean to indicate whether the scroller is finished. If it isn't, it means that a fling or programmatic pan operation is still in progress. You can use this method to find the current offsets of the x and y coordinates, for example:

  • 要跟踪x / y坐标的变化位置,请使用computeScrollOffset()。 该方法返回一个布尔值以指示滚动程序是否完成。 如果还没有完成,这意味着一个甩动操作或程序化的平移操作仍在进行中。 你可以使用此方法获得x和y坐标的当前偏移量,例如:

    if (mScroller.computeScrollOffset()) {
     // Get current x and y positions
     int currX = mScroller.getCurrX();
     int currY = mScroller.getCurrY();
    ...
      }
    

概要说明


  • Scroller提供了三个构造函数
  • Scroller(Context context)
    Create a Scroller with the default duration and interpolator.
    使用默认的持续时间值和插值器创建一个Scroller
  • Scroller(Context context, Interpolator interpolator)
    Create a Scroller with the specified interpolator.
    使用指定的插值器创建一个Scroller,持续时间之还是默认的250
  • Scroller(Context context, Interpolator interpolator, boolean flywheel)
    Create a Scroller with the specified interpolator.

摘录自:http://blog.csdn.net/vipzjyno1/article/details/24592591动画效果:

  • AccelerateDecelerateInterpolator: 开始和结束都是缓慢的,通过中间时候加速
  • AccelerateInterpolator:先缓慢,后加速
  • AnticipateInterpolator:先后退,后前进
  • AnticipateOvershootInterpolator:开始后退,然后前进并超过终点位置,最终退回到终点
  • BounceInterpolator:弹性衰减到结束
  • CycleInterpolator:重复循环动画,速度变化遵循正弦定律
  • DecelerateInterpolator:先加速,后减速
  • LinearInterpolator:线性的
  • OvershootInterpolator:超过终点然回来

scroller method

  • void abortAnimation()
    滚到最终的x,y位置中止动画。
  • boolean computeScrollOffset()
    调用该方法计算,获取当前的位置。
    void extendDuration(int extends)
    扩展滚动动画。
    void fling(int startX,int startY,int velocityX,int velocityY,int minX,int maxX,int minY,int maxY)
    开始滚动基于一个拖拽手势。
    final void forceFinished(boolean finished)
    强行停止滚动。
    float getCurrVelocity()
    返回当前滚动速度。
    final int getCurrX()
    返回滚动中当前的X偏移量。
    final int getCurrY()
    返回滚动中当前的Y偏移量。
    final int getDuration()
    返回滚动事件将花费多长时间,以毫秒为单位。
    final int getFinalX()
    返回滚动结束的x坐标值。
    最终int getFinalY()
    返回滚动结束的y坐标值。
    final int getStartX()
    返回滚动中的起始X偏移量。
    final int getStartY()
    返回滚动中的起始Y偏移量。
    final boolean isFinished()
    返回滚动滚轮是否完成滚动。
    void setFinalX(int newX)
    设置此滚动条的最终位置(X)。
    void setFinalY(int newY)
    设置此滚动条的最终位置(Y)。
    final setFriction(float friction)
    设置摩擦力的摩擦量。
    void startScroll(int startX,int startY,int dx,int dy,int duration)
    通过提供起点,行程距离和滚动持续时间来开始滚动。
    void startScroll(int startX,int startY,int dx,int dy)
    通过提供起点和行驶距离开始滚动。
    int timePassed()
    返回自滚动开始以来经过的时间。

引言


  • 在自定义View中需要制作滚动效果的时候我们会经常遇到这个类,当然也可以通过属性动画或者补间动画实现,但是使用scroller实现有个好处,你可以中途取消滚动效果。

Scroller


  • 官方文档也说了,Scroller负责收集滚动所需的数据,也就是说,Scroller本身并不负责“滚动”这个操作,滚动的操作是有View的scrollTo(x,y) 和scollerBy(dx,dy)这两个方法完成的。而使用Scroller实现滚动时,比如我们想让view向下滚动,此时我是一脸懵逼的,要怎么触发呢?其实Scroller需要容器类配合实现这个滚动过程,比如一个viewgroup中的childview1 想滚动,触发该滚动的并不事childview1自己,而是viewgroup触发的。如果你在TextView中使用Scroller,那么滚动时移动的其实是TextView的可视区域,TextView本身并未移动。
    这个理解起来可能比较变扭,我们来借助图形理解一下:
111.png

如上图:view1从右边往左下滚动,其实内部是将viewgroup的可视区域往右移动了,
使用Scroller时,最长用的方法就是scrollTo 和ScrollBy,有关这两个方法的使用介绍和区别,网上其实有很多相关的文章。

  • ScrollTo(int x, int y) 我只要见过,不管你过程如何 ----滑动到(x,y)这个点,不管你怎么跑,你最后得给我滚到这个点就对了。

  • 接下来我们来个一简单的demo实践一下:先看效果图
2017-04-17 17_52_43.gif
  • 代码如下:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout     xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    tools:context="guanaj.com.scrollerdemo.MainActivity">
    <LinearLayout
      android:id="@+id/ll_content"
      android:layout_width="match_parent"
      android:background="@android:color/holo_green_light"
      android:layout_height="wrap_content">
      <TextView
          android:layout_marginTop="6dp"
          android:layout_marginBottom="6dp"
          android:background="@android:color/holo_red_dark"
          android:text="我滚"
          android:gravity="center"
          android:id="@+id/txt"
          android:layout_width="50dp"
          android:layout_height="50dp" />
    </LinearLayout>
      <Button
        android:layout_marginTop="20dp"
        android:id="@+id/start_scrollby"
      android:text="scrollBy"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content" />
    <Button
      android:id="@+id/start_scrollto"
      android:text="scrollTO"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content" />
    </LinearLayout>
    
  • 本次是让textView进行滚动

  • 看实现代码

    package guanaj.com.scrollerdemo;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.LinearLayout;
    import android.widget.Scroller;
    import android.widget.TextView;
    
    public class MainActivity extends AppCompatActivity {
    
    private Scroller scroller;
    private LinearLayout llContent;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      Button startScrollby = (Button) findViewById(R.id.start_scrollby);
      Button startScrollto = (Button) findViewById(R.id.start_scrollto);
    
      llContent = (LinearLayout) findViewById(R.id.ll_content);
    
      TextView txt = (TextView) findViewById(R.id.txt);
      //初始化Scroller
      scroller = new Scroller(this);
      startScrollby.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              startScrollby();
          }
      });
      startScrollto.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              startScrollto();
          }
      });
    
    }
    
    private void startScrollby() {
      llContent.scrollBy(-100,0);
    
    }
    private void startScrollto() {
      llContent.scrollTo(0,0);
    
    }
    }
    
  • 当点击startScrollby的时,让LinearLayout里面的textview向右滚动100px,这里为什么是-100呢,按照坐标轴来说100才是向右移动才对啊!
  • 当时我也是一脸懵逼的,突然一想,不对,移动的并不是textview,而是linearlayout的可视区域,视觉上的textview向右滚,其实是linearlayout的可视区域向左移动,所以是-100;当点击startScrollto的时候,我们让linearlayout的可视区域回到原点。
  • 由于上传文件大小限制,效果图的速度是被加快了的,其实滑动是一下子就滚到一个点的,没有动画效果。这种体验是及不好的。接下来我们就来实现平滑的滚动,让他潇洒滚一回吧!

平滑的滚吧!蛋炒饭~~

突然想另起一章来继续解析scroller,不要打我,请看下一章节

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容