zoukankan      html  css  js  c++  java
  • 【Android】Scroller分析

    综合两篇博客:Android Scroller简单用法android 使用Scroller实现缓慢移动

    API:

     1 mScroller.getCurrX() //获取mScroller当前水平滚动的位置
     2 mScroller.getCurrY() //获取mScroller当前竖直滚动的位置
     3 mScroller.getFinalX() //获取mScroller最终停止的水平位置
     4 mScroller.getFinalY() //获取mScroller最终停止的竖直位置
     5 mScroller.setFinalX(int newX) //设置mScroller最终停留的水平位置,没有动画效果,直接跳到目标位置
     6 mScroller.setFinalY(int newY) //设置mScroller最终停留的竖直位置,没有动画效果,直接跳到目标位置
     7 
     8 //滚动,startX, startY为开始滚动的位置,dx,dy为滚动的偏移量, duration为完成滚动的时间
     9 mScroller.startScroll(int startX, int startY, int dx, int dy) //使用默认完成时间250ms
    10 mScroller.startScroll(int startX, int startY, int dx, int dy, int duration)
    11 
    12 mScroller.computeScrollOffset() //返回值为boolean,true说明滚动尚未完成,false说明滚动已经完成。这是一个很重要的方法,通常放在View.computeScroll()中,用来判断是否滚动是否结束。

    先上源代码:

     1 import android.content.Context;
     2 import android.util.AttributeSet;
     3 import android.util.Log;
     4 import android.view.View;
     5 import android.widget.LinearLayout;
     6 import android.widget.Scroller;
     7 
     8 public class CustomView extends LinearLayout {
     9 
    10     private static final String TAG = "Scroller";
    11 
    12     private Scroller mScroller;
    13 
    14     public CustomView(Context context, AttributeSet attrs) {
    15         super(context, attrs);
    16         mScroller = new Scroller(context);
    17     }
    18 
    19     //调用此方法滚动到目标位置
    20     public void smoothScrollTo(int fx, int fy) {
    21         int dx = fx - mScroller.getFinalX();
    22         int dy = fy - mScroller.getFinalY();
    23         smoothScrollBy(dx, dy);
    24     }
    25 
    26     //调用此方法设置滚动的相对偏移
    27     public void smoothScrollBy(int dx, int dy) {
    28 
    29         //设置mScroller的滚动偏移量
    30         mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, dy);
    31         invalidate();//这里必须调用invalidate()才能保证computeScroll()会被调用,否则不一定会刷新界面,看不到滚动效果
    32     }
    33     
    34     @Override
    35     public void computeScroll() {
    36     
    37         //先判断mScroller滚动是否完成
    38         if (mScroller.computeScrollOffset()) {
    39         
    40             //这里调用View的scrollTo()完成实际的滚动
    41             scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
    42             
    43             //必须调用该方法,否则不一定能看到滚动效果
    44             postInvalidate();
    45         }
    46         super.computeScroll();
    47     }
    48 }

    我们先来看一下,Scroller,这个对象里有startScroll方法 

    void android.widget.Scroller.startScroll(int startX, int startY, int dx, int dy, int duration)
    第一个参数是起始移动的x坐标值,第二个是起始移动的y坐标值,第三个第四个参数都是移到某点的坐标值,而duration 当然就是执行移动的时间。这个有什么用呢。要知道有什么用还得再看一个方法

    boolean android.widget.Scroller.computeScrollOffset()

    当startScroll执行过程中即在duration时间内,computeScrollOffset  方法会一直返回false,但当动画执行完成后会返回返加true.

    有了这两个方法还不够,我们还需要再重写viewGroup的一个方法,

    computeScroll 这个方法什么时候会被调用呢

    官网上这样说的

    public void computeScroll ()

    Since: API Level 1

    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 Scroller object.

    当我们执行ontouch或invalidate()或postInvalidate()都会导致这个方法的执行

    所以我们像下面这样调用,postInvalidate执行后,会去调computeScroll 方法,而这个方法里再去调postInvalidate,这样就可以不断地去调用scrollTo方法了,直到mScroller动画结束,当然第一次时,我们需要手动去调用一次postInvalidate才会去调用 

  • 相关阅读:
    EntityFramework优缺点
    领导者与管理者的区别
    七个对我最好的职业建议(精简版)
    The best career advice I’ve received
    Difference between Stored Procedure and Function in SQL Server
    2015年上半年一次通过 信息系统项目管理师
    Difference between WCF and Web API and WCF REST and Web Service
    What’s the difference between data mining and data warehousing?
    What is the difference between a Clustered and Non Clustered Index?
    用new创建函数的过程发生了什么
  • 原文地址:https://www.cnblogs.com/lqminn/p/2867035.html
Copyright © 2011-2022 走看看