View的scrollTo和scrollBy

参考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()的偏移位置是相对于当前位置的偏移位置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值