笔记6 | 从源码理解分析mScrollX和mScrollY,scrollTo()和scrollBy(),smoothScrollTo和smoothScrollBy

来源:互联网 发布:windows phone8评测 编辑:程序博客网 时间:2024/06/13 14:13

前言

我想开头先说说

a.度娘一下什么都知道了,整理这些东西有什么用?还费时费力的!如何才能完全掌握一个知识?当你能把它讲清楚的时候,你才算掌握了他。

想完全把mScrollX和mScrollY,scrollTo()和scrollBy(),smoothScrollTo和smoothScrollBy弄明白并不容易,但查阅他们的源代码基本就能明白个大概,这篇文章就是从源码分析他们究竟有什么作用和区别,读懂了基本就会用!


公众号


目录

  • mScrollX和mScrollY
  • scrollTo()和scrollBy()
  • smoothScrollBy和smoothScrollTo
  • view和viewgroup

一.mScrollX和mScrollY

  1. /**
  2. * The offset, in pixels, by which the content of this view is scrolled
  3. * horizontally.
  4. * {@hide}
  5. */
  6. @ViewDebug.ExportedProperty(category = "scrolling")
  7. protected int mScrollX;
  8. /**
  9. * The offset, in pixels, by which the content of this view is scrolled
  10. * vertically.
  11. * {@hide}
  12. */
  13. @ViewDebug.ExportedProperty(category = "scrolling")
  14. protected int mScrollY;
  15. /**
  16. * Return the scrolled left position of this view. This is the left edge of
  17. * the displayed part of your view. You do not need to draw any pixels
  18. * farther left, since those are outside of the frame of your view on
  19. * screen.
  20. *
  21. * @return The left edge of the displayed part of your view, in pixels.
  22. */
  23. public final int getScrollX() {
  24. return mScrollX;
  25. }
  26. /**
  27. * Return the scrolled top position of this view. This is the top edge of
  28. * the displayed part of your view. You do not need to draw any pixels above
  29. * it, since those are outside of the frame of your view on screen.
  30. *
  31. * @return The top edge of the displayed part of your view, in pixels.
  32. */
  33. public final int getScrollY() {
  34. return mScrollY;
  35. }

直接翻译就可以得知

mScrollX:表示离视图起始位置的x水平方向的偏移量

mScrollY:表示离视图起始位置的y垂直方向的偏移量

通过getScrollX() 和getScrollY()方法获这兄弟俩。注意:mScrollX和mScrollY指的并不是坐标,而是偏移量


二.scrollTo()和scrollBy()

  1. <span style="font-family:SimSun;font-size:14px;"> /**
  2. * Set the scrolled position of your view. This will cause a call to
  3. * {@link #onScrollChanged(int, int, int, int)} and the view will be
  4. * invalidated.
  5. * @param x the x position to scroll to
  6. * @param y the y position to scroll to
  7. */
  8. public void scrollTo(int x, int y) {
  9. if (mScrollX != x || mScrollY != y) {
  10. int oldX = mScrollX;
  11. int oldY = mScrollY;
  12. mScrollX = x;
  13. mScrollY = y;
  14. invalidateParentCaches();
  15. onScrollChanged(mScrollX, mScrollY, oldX, oldY);
  16. if (!awakenScrollBars()) {
  17. postInvalidateOnAnimation();
  18. }
  19. }
  20. }
  21. /**
  22. * Move the scrolled position of your view. This will cause a call to
  23. * {@link #onScrollChanged(int, int, int, int)} and the view will be
  24. * invalidated.
  25. * @param x the amount of pixels to scroll by horizontally
  26. * @param y the amount of pixels to scroll by vertically
  27. */
  28. public void scrollBy(int x, int y) {
  29. scrollTo(mScrollX + x, mScrollY + y);
  30. }</span>

源码可以看出,scrollTo 和 scrollBy区别,其实2者的效果是一样的,只是过程不同而已。

scrollTo(int x,int y):

如果偏移位置发生了改变,就会给mScrollX和mScrollY赋新值,改变当前位置。注意:x,y代表的不是坐标点,而是偏移量。例如:我要移动view到坐标点(100,100),那么我的偏移量就是(0,,0) - (100,100) = (-100 ,-100) ,我就要执行view.scrollTo(-100,-100),达到这个效果。

scrollBy(int x,int y):

从源码中看出,它实际上是调用了scrollTo(mScrollX + x, mScrollY + y);mScrollX + x和mScrollY + y,即表示在原先偏移的基础上在发生偏移,通俗的说就是相对我们当前位置偏移。根据父类VIEW里面移动,如果移动到了超出的地方,就不会显示。


三.smoothScrollTo和smoothScrollBy

ScrollView.smoothScrollBy和smoothScrollTo的源码

  1. /**
  2. * Like {@link View#scrollBy}, but scroll smoothly instead of immediately.
  3. *
  4. * @param dx the number of pixels to scroll by on the X axis
  5. * @param dy the number of pixels to scroll by on the Y axis
  6. */
  7. public final void smoothScrollBy(int dx, int dy) {
  8. if (getChildCount() == 0) {
  9. // Nothing to do.
  10. return;
  11. }
  12. long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
  13. if (duration > ANIMATED_SCROLL_GAP) {
  14. final int height = getHeight() - mPaddingBottom - mPaddingTop; //获取部件高度
  15. final int bottom = getChildAt(0).getHeight(); //获取当前能看到的item高度
  16. final int maxY = Math.max(0, bottom - height);
  17. final int scrollY = mScrollY;
  18. dy = Math.max(0, Math.min(scrollY + dy, maxY)) - scrollY;
  19. mScroller.startScroll(mScrollX, scrollY, 0, dy);
  20. postInvalidateOnAnimation();
  21. } else {
  22. if (!mScroller.isFinished()) {
  23. mScroller.abortAnimation();
  24. if (mFlingStrictSpan != null) {
  25. mFlingStrictSpan.finish();
  26. mFlingStrictSpan = null;
  27. }
  28. }
  29. scrollBy(dx, dy);
  30. }
  31. mLastScroll = AnimationUtils.currentAnimationTimeMillis();
  32. }
  33. /**
  34. * Like {@link #scrollTo}, but scroll smoothly instead of immediately.
  35. *
  36. * @param x the position where to scroll on the X axis
  37. * @param y the position where to scroll on the Y axis
  38. */
  39. public final void smoothScrollTo(int x, int y) {
  40. smoothScrollBy(x - mScrollX, y - mScrollY);
  41. }

源码可以看出,是ScrollBy和ScrollTo增加滚动动画的升级方案;

moothScrollBy(int dx, int dy) :

 dy = Math.max(0, Math.min(scrollY + dy, maxY)) - scrollY;为方法的核心,比较绕,大致为计算当前滑动状态下可划动距离;

if(duration > ANIMATEDSCROLLGAP) 这句是判断当前是否在滚动,当还在滚动状态下,执行mScroller.startScroll(mScrollX, scrollY, 0, dy);当不在滚动,就立马打断。

smoothScrollTo(int x, int y):

 它实际上是调用了smoothScrollBy(x - mScrollX, y - mScrollY);方法根据x,y的值来计算剩余可滚动的位移量;


四.view和viewgroup

最后讲讲view和viewgroup这俩,完全吃透有点难,通俗讲,Android的UI界面都是由View和ViewGroup及其派生类组合而成的,View是所有UI组件的基类,而ViewGroup是容纳这些组件的容器;View类是ViewGroup的父类,ViewGroup具有View的所有特性,ViewGroup主要用来充当View的容器,将其中的View作为自己孩子,并对其进行管理,当然孩子也可以是ViewGroup类型。

View派生出的直接子类有:AnalogClock,ImageView,KeyboardView, ProgressBar,SurfaceView,TextView,ViewGroup,ViewStubView派生出的间接子类有:AbsListView,AbsSeekBar, AbsSpinner, AbsoluteLayout, AdapterView,AdapterViewAnimator, AdapterViewFlipper, AppWidgetHostView, AutoCompleteTextView,Button,CalendarView, CheckBox, CheckedTextView, Chronometer, CompoundButton

ViewGroup派生出的直接子类有:AbsoluteLayout,AdapterView,FragmentBreadCrumbs,FrameLayout,LinearLayout,RelativeLayout,SlidingDrawer;

ViewGroup派生出的间接子类有:AbsListView,AbsSpinner, AdapterViewAnimator, AdapterViewFlipper, AppWidgetHostView, CalendarView, DatePicker, DialerFilter, ExpandableListView, Gallery, GestureOverlayView,GridView,HorizontalScrollView, ImageSwitcher,ListView,

当然,随着Android版本不断地更新,这些派生出来的子类也是在不段增加的!

END

阅读全文
0 0
原创粉丝点击