View的scrollTo和scrollBy

来源:互联网 发布:mac cp 拷贝文件夹 编辑:程序博客网 时间:2024/05/16 09:31

参考http://xroocky.github.io/2016/05/30/ScrollTo%E5%92%8CScrollBy/

注意:

  • 这两个方法移动的并不是View本身。
  • 如果该View没有子View,那么移动的就是View的内容(比如说调用一个Button的相应方法,会发现Button本身并不会移动,移动 的是Button的文本内容)。
  • 如果该View中有子View,那么移动的就是子View(比如说一个FrameLayout中有一个Button,调用FrameLayout的相应方法,会发现Button移动而FrameLayout不移动)
  • scrollTo(int, int)
    让View的content滚动到相对View初始位置的(x, y)处,可以看到这里:mScrollX和mScrollY是保存这个view相对于起点坐标的偏移量,如果这次传进来的值和上一次滑动到的位置已经一致,则不做任何处理,如果不一样则进行滑动

    public void scrollTo(int x, int y) {    if (mScrollX != x || mScrollY != y) {        int oldX = mScrollX;        int oldY = mScrollY;        mScrollX = x;        mScrollY = y;        invalidateParentCaches();        onScrollChanged(mScrollX, mScrollY, oldX, oldY);        if (!awakenScrollBars()) {            postInvalidateOnAnimation();        }    }}

    方法名带有to,给人的感觉就是移动到坐标为(x, y)的地方,其实实践的结果并不是这样,而是移动到偏移位置为(x, y)的地方。那么问题就来了,这个偏移是相对哪里偏移呢?实践结果是相对初始位置的偏移。
    举个例子,如果在当前布局中存在一个Button,那么此时的初始位置为(0, 0),mScrollX和mScrollY均为0。如果调用button.scrollTo(5, 5)的话,那么移动后的位置就是“初始位置”减去“偏移位置”即:(x, y) = (0, 0) - (5, 5) = (-5, -5),所以button中的文字会向左向上分别移动5个像素。此时的mScrollX和mScrollY均为5,因为在源码中可以看到mScrollX和mScrollY被赋值。如果再次调用button.scrollTo(5, 5),可以看到源码会先进行判断,当然自然是无法再次进入if代码段。

  • scrollBy(int, int)
    让View的content滚动到相对于View当前位置的(x, y)处,这个方法实际是调用了上面的scrollTo方法,并且滑动的位置是上一次滑动到的位置加上传入的偏移值,所以传入的值如果不同时为0,则肯定会触发滑动

    public void scrollBy(int x, int y) {    scrollTo(mScrollX + x, mScrollY + y);}

    方法名带有by,给人的感觉就是在当前位置的基础上移动(x, y),这次没问题,就是这样移动的。这里的偏移位置(x, y)就是相对于当前位置的偏移位置。
    还拿上个例子来说,已经调用过一次button.scrollTo(5, 5)后再次调用会发现不会再移动,因为无法再次进入if语句。如果此时调用button.scrollBy(5, 5)呢?可以看到源码中分别给当前的mScrollX和mScrollY加了x和y,那么此时传入scrollTo方法的参数就是(10, 10),相当于直接调用了button.scrollTo(10, 10),在if语句判断时就可以成功进入if语句。

  • 总结
    scrollTo()和scrollBy()的参数均为偏移位置,不同之处在于scrollTo()的偏移位置是相对于初始位置的偏移位置,而scrollBy()的偏移位置是相对于当前位置的偏移位置。

0 0