通过一张图理解 scrollBy()与scrollTo()的区别

通过字面意思,scrollTo是指移动到某一位置,scrollBy该怎么理解呢?
先看一下两者的源码
scrollTo:
在这里插入图片描述
scrollBy:
在这里插入图片描述
根据源码的实现,参数x是水平移动的位置,y是垂直方向移动的位置
scrollBy调用了scrollTo方法;
scrollBy是在上一次移动的位置的(mScrollX和mScrollY)基础上进行逸动的;
scrollTo是直接移动到(x,y)的位置

需要注意的是,scrollTo和scrollBy都是移动的内容,而不是将View做整体的移动,对于一个TextView而言,文本就是它的内容;对于一个ViewGroup而言,子View就是它的内容

不论scrollBy还是scrollTo最后都调用了postInvalidateOnAnimation()方法对View进行重绘从而执行到invalidate()方法
在这里插入图片描述
我们知道Android中的屏幕坐标系零点在屏幕左上角,向右是x轴正方向,向下是y轴正方向。

再看源码,l、t、r、b分别是View的左、上、右、下边界所在的位置,在invalidate方法中,将mScrollX和mScrollY分别赋值给了scrollX和scrollY
然后l、t和r、b分别用参数中传入的数据减去了scrollX和scrollY的距离,这样造成的结果就是:
t和b的值会越来越小,界面上的表现就是:

如果我连续调用两次sc

### `scrollBy` `scrollTo` 的区别Android 中,`scrollBy(int x, int y)` 和 `scrollTo(int x, int y)` 是用于实现视内容滚动的核心方法。二者的主要区别在于它们对视内容偏移量的处理方式不同。 - `scrollTo(int x, int y)` 直接设置当前视的内容偏移量。具体而言,该方法会将视内容移动到指定的绝对位置,其中 `x` 表示水平方向上的偏移,`y` 表示垂直方向上的偏移。这意味着如果当前视已经发生了滚动,再次调用 `scrollTo` 会直接跳转到新的位置,而不是基于当前状态进行增量调整[^1]。 - `scrollBy(int x, int y)` 则是基于当前的偏移量进行增量调整。它会在现有滚动位置的基础上加上传入的 `x` 和 `y` 值,从而实现连续滚动的效果。例如,如果当前的 `mScrollX` 是 50,调用 `scrollBy(-10, 0)` 后,`mScrollX` 将变为 40,表示视内容向右移动了 10 像素[^1]。 这两个方法都直接影响 `View` 内部的 `mScrollX` 和 `mScrollY` 变量,这些变量分别表示视左边缘其内容左边缘之间的水平距离和视上边缘其内容上边缘之间的垂直距离。通过调整这些值,可以控制视内容相对于其可视区域的位置。 ### 示例代码 以下是一个简单的示例,展示如何使用 `scrollTo` 和 `scrollBy` 实现视内容的滚动: ```java public class ScrollableView extends View { private Scroller mScroller; public ScrollableView(Context context) { this(context, null); } public ScrollableView(Context context, AttributeSet attrs) { super(context, attrs); mScroller = new Scroller(context); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); awakenScrollBars(); } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); postInvalidate(); } super.computeScroll(); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (!mScroller.isFinished()) { mScroller.abortAnimation(); } break; case MotionEvent.ACTION_MOVE: int deltaX = (int) (event.getX() - getWidth() / 2); scrollBy(-deltaX, 0); break; case MotionEvent.ACTION_UP: mScroller.startScroll(getScrollX(), getScrollY(), -getScrollX(), 0, 500); postInvalidate(); break; } return true; } } ``` 在上述代码中,`scrollBy` 被用来根据用户的滑动手势动态调整视内容的位置,而 `scrollTo` 在 `computeScroll()` 方法中被用来实现平滑滚动效果。 ### 滚动行为的实际应用 在实际开发中,`scrollTo` 和 `scrollBy` 经常 `Scroller` 或 `OverScroller` 结合使用,以实现更复杂的滚动动画。例如,在自定义 `ViewGroup` 或 `RecyclerView` 的布局管理器中,可以通过 `Scroller` 控制滚动的持续时间和速度,同时结合 `scrollTo` 或 `scrollBy` 来更新视的滚动状态。 此外,当视内容发生缩放时(如地像编辑器),`scrollBy` 还可用于调整视的滚动偏移,以保持缩放中心点不变。例如,在缩放操作中,可以通过计算缩放前后的差值并调用 `scrollBy` 来实现视觉上的居中效果。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值