# Android 滑动探究
## 1. Android 坐标系
Android 都是以左上角作为坐标原点
## 2. Android Scroll
针对Android view 的 滑动,即Scroll , 常见的是View实现滑动主要靠三种方式:
+ srollTo/scrollBy等由系统提供的API
+ 通过位移动画实现View的滑动
+ 为View设置LayoutParams,触发View重新布局
### 2.1 scrollTo/scrollBy 方法
这两个应该是业务中实现滑动最常用的两个函数
- scrollTo(int x, int y)
```
/**
* Set the scrolled position of your view. This will cause a call to
* {@link #onScrollChanged(int, int, int, int)} and the view will be
* invalidated.
* @param x the x position to scroll to
* @param y the y position to scroll to
*/
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();
}
}
}
```
- scrollBy(int x, int y)
```
/**
* Move the scrolled position of your view. This will cause a call to
* {@link #onScrollChanged(int, int, int, int)} and the view will be
* invalidated.
* @param x the amount of pixels to scroll by horizontally
* @param y the amount of pixels to scroll by vertically
*/
public void scrollBy(int x, int y) {
scrollTo(mScrollX + x, mScrollY + y);
}
```
可以看到本质上scrollBy底层也是调用scrollTo,有源码可以判断出,scrolltTo()是实现到(x,y)坐标的绝对滑动,scrollBy()则是相对于当前坐标进行相对滑动,这里要对mScrollX,mScrollY,两个参数的概率有所了解:
- mScrollX :
```
* The offset, in pixels, by which the content of this view is scrolled
* horizontally.
* Please use {@link View#getScrollX()} and {@link View#setScrollX(int)} instead of
* accessing these directly.
```
这里翻译过来是指视图滚动的偏移量(px),这里引用开发探索中的概括mScrollX的值恒等于View左边缘和View内容左边缘在水平的距离,还是有点难懂, **这里View的边缘就是正常理解View的边界,而scroll是不会改变View边界位置,只是改变view的内容位置** ,并且当View的左边缘在view内容的右边时,可以理解为此时滑动应该是往左方向移动,造成view内容左边界往左侧移动,此时mScrollX的值为正值,所以这里我的理解应该是正负表示方向,数组代表偏移量,内容左偏为正,反之为负。
- mScrollY :
```
/**
* The offset, in pixels, by which the content of this
* view is scrolled
* vertically.
**/
```
这里mScrollY同理,表示view上边缘和内容上边缘的距离,内容上偏为正,反之为负。
这里注意的是,scrollBy/scrollTo均为无过渡滑动,这里如果需要用户感知,可借助Scroller构造自己的smoothScrollto()方法,而RecycleView内以为我们封装了这套方法,其底层也是Scroller实现。
```
public void smoothScrollBy(int dx, int dy, int duration, Interpolator interpolator) {
if (mInterpolator != interpolator) {
mInterpolator = interpolator;
mScroller = new OverScroller(getContext(), interpolator);
}
setScrollState(SCROLL_STATE_SETTLING);
mLastFlingX = mLastFlingY = 0;
mScroller.startScroll(0, 0, dx, dy, duration);
if (Build.VERSION.SDK_INT < 23) {
// b/64931938 before API 23, startScroll() does not reset getCurX()/getCurY()
// to start values, which causes fillRemainingScrollValues() put in obsolete values
// for LayoutManager.onLayoutChildren().
mScroller.computeScrollOffset();
}
postOnAnimation();
}
```
## 2.2 借助translate动画实现
这里的滑动就不是用户手动触发滑动了
## 2.3 设置LayoutParam 触发view重新布局
设置layoutParam一般用户动态改变View的属性,怎么滑动起来呢,你可以让marginLeft 借助属性动画(ValueAnimator)累加起来,不就动起来了嘛。
# 3. RecycleView的滑动
未完待更
网友评论