重识ScrollTo或ScrollBy

相信大家都很熟悉scrollTo()或scrollBy()方法;网上也很多关于scrollTo()或scrollBy()方法的使用或讲解。但对于我这种数学渣来说,感觉有点糊涂,不够深入。
今天我重新认识一下scrollTo()或scrollBy()方法。

1.1scrollTo()或scrollBy()方法

  • 首先该方法是View类的:
重识ScrollTo或ScrollBy_第1张图片
scrollTo()或scrollBy()方法

非Scroller类,这个是第一个认知;(我也相信很多人会知道的,哈哈...)

1.2 scrollBy()方法里面调用scrollTo()方法

重识ScrollTo或ScrollBy_第2张图片
scrollBy()方法

相信这个也是大家所认知的,对于不耐烦的童鞋,可能直接关闭页面了,O(∩_∩)O哈哈~;

好吧,客官别急,慢慢来嘛,对于我这种学渣来说,为了巩固知识能一个个点记住。

1.2.1scrollTo()方法

我们先看看scrollTo方法,的解释:

重识ScrollTo或ScrollBy_第3张图片
Paste_Image.png

意译:设置你的view的滑动位置。这个会调用onScrollChanged()方法和view的invalidate()方法也会调用。

个人总结:起码这里你会发现原来调用scrollTo(x,y)方法会调用到

重识一:onDraw()方法

(invalidate方法会调用onDraw方法);

1.2.2 scrollTo方法的正负问题

戏肉来了:
Android Scroller完全解析,关于Scroller你所需知道的一切
这是郭霖郭大神写的关于View的滑动博客:

Paste_Image.png
Paste_Image.png

这里只看X轴郭大神所说相对于当前位置横向移动的距离;正值向左移动,负值向右;

第一个关键点就出现在这里;当然你可以简单地理解为正值向左移动,负值向右移动。

但是

  • 首先需要说明一点View.scrollTo()方法是View的内容移动到指定的位置;怎样理解这句话呢?
    View.scrollTo(-100); 相信看了郭大神的博客很清楚会知道是View的内容移动到 -100那个位置,再调用View.scrollTo(-100);View的内容就不动了。就是上面说的移动到指定位置,这里是与scrollBy()方法不同的。
    上面我说的是View的内容非View本身;非View本身;非View本身;

什么是View的内容

在任大神任玉刚的《Android开发艺术探索》一书中也提到了View的内容这一说;

根据我的实践经验告诉我View的内容:对于View来说就是draw()内面绘制的内容,即对于View来说View的内容就是绘制内容。
对于ViewGroup来说View的内容就是子View。

重识二:

对于View来说View的内容就是绘制内容。
对于ViewGroup来说View的内容就是子View。

看看郭大神这张图片:

重识ScrollTo或ScrollBy_第4张图片
scrollTOorBy.gif

这里看到两个按钮每点击SCROLLBY就向下移动;看看郭大神的代码:

重识ScrollTo或ScrollBy_第5张图片
Paste_Image.png

是 layout.scrollBy(-60, -100);

即是LinearLayout的内容在移动所以这里证明我上面所说的观点。非LinearLayout本身在移动。

《Android开发艺术探索》书中说onLayout()方法已经将View本身的位置定了下来,scrollTo()或scrollBy()非移动View本身,是其内容。

正负问题

scrollTo(-60,0);按照郭大神所说的向右移动60个像素。

在调用完scrollTo(-60,0);这行代码后再调用scrollTo(-30,0);
View的内容是向左滑动的。(不了解的童鞋可以自己在代码尝试一下)
我说的是调用完scrollTo(-60,0);再调用scrollTo(-30,0);非直接调用scrollTo(-30,0);

重识三:

“正负号相对于当前位置向左向右移动”的说法对于scrollTo()方法不准确;对于scrollBy()方法是准确的。
对于scrollTo()方法,正负数值是View内容移动到指定位置,这个位置的正负是基于View的坐标系决定的

1.2.3 View的坐标系对于scrollTo方法的影响

看看这个gif:


重识ScrollTo或ScrollBy_第6张图片
ScrollTo方法.gif

这个就是scrollTo(x,y)方法的工作过程。-60,-30,0就是scrollTo的第一个参数X轴位置。这里的坐标(-60,0) (-30,0) (0,0)是基于View本身位置的最左边为基准点。这个工作过程与屏幕的坐标系或右正左负,上负下正时一致的,所以可以解释到为什么负是向右滑动,正向左滑动。

1.2 scrollBy()方法

通过上面的认识再了解scrollBy()方法就简单多了。

重识ScrollTo或ScrollBy_第7张图片
Paste_Image.png

上面已经说了scrollBy()是调用scrollTo()方法,而且是基于mScrollX的基础上再加传入的参数所以scrollBy就是滑动距离,非滑动到指定位置。

这里的mScrollX或mScrollY其实就是之前getScrollX()或getScrollY()的值即上次滑动的指定位置坐标X或Y值

2 郭大神这段代码的疑惑

重识ScrollTo或ScrollBy_第8张图片
Paste_Image.png

对于我这种数学渣来说这段代码本身很疑惑的,但现在明白了。

疑惑一:getWidth()

该值其实就是ViewPager的宽,但该宽必不是ViewPager所有子View宽度的叠加(一般情况下VIewGroup的宽度就是所有子View的宽度叠加),而是基于ViewPager父类的宽所定和自身设定的宽度,这里假设ViewPager宽设置了MATCH_PARENT而父类的宽也是MATCH_PARENT,那么ViewPager的getWidth()就是屏幕的宽度。以上说的宽度忽略padding。

疑惑二:getScrollX()

getScrollX() 是什么玩意呢?
其实就是基于上次滑动scrollTo(x,y);方法中的x;getScrollY()对应y;
那么:int targetIndex = (getScrollX() + getWidth() / 2) / getWidth();
就是指:当滑动到一半的情况下,通过getScrollX()的一半来决定是停留在当前或是下一页。

疑惑三: int dx = targetIndex * getWidth() - getScrollX();

指:dx就是滑动余下的距离加减getScrollX()是基于绘制滑动内容是一个相对距离非绝对距离。(这句话可以看看我上边自己做的gif,慢慢消化)

最后以上说明没有贬低郭霖郭大神之意。这里记录一下自己对scrollTo和scrollBy的理解。还是对郭大神对Android学习的奉献精神表示赞赏和支持。O(∩_∩)O哈哈~

你可能感兴趣的:(重识ScrollTo或ScrollBy)