前言
我想開頭先說說
a.度娘一下什么都知道了,整理這些東西有什么用?還費時費力的!如何才能完全掌握一個知識?當你能把它講清楚的時候,你才算掌握了他。
想完全把mScrollX和mScrollY,scrollTo()和scrollBy(),smoothScrollTo和smoothScrollBy弄明白并不容易,但查閱他們的源代碼基本就能明白個大概,這篇文章就是從源碼分析他們究竟有什么作用和區別,讀懂了基本就會用!
公眾號
目錄
- mScrollX和mScrollY
- scrollTo()和scrollBy()
- smoothScrollBy和smoothScrollTo
- view和viewgroup
/** * The offset, in pixels, by which the content of this view is scrolled * horizontally. * {@hide} */ @ViewDebug.ExportedProperty(category = "scrolling") protected int mScrollX; /** * The offset, in pixels, by which the content of this view is scrolled * vertically. * {@hide} */ @ViewDebug.ExportedProperty(category = "scrolling") protected int mScrollY; /** * Return the scrolled left position of this view. This is the left edge of * the displayed part of your view. You do not need to draw any pixels * farther left, since those are outside of the frame of your view on * screen. * * @return The left edge of the displayed part of your view, in pixels. */ public final int getScrollX() { return mScrollX; } /** * Return the scrolled top position of this view. This is the top edge of * the displayed part of your view. You do not need to draw any pixels above * it, since those are outside of the frame of your view on screen. * * @return The top edge of the displayed part of your view, in pixels. */ public final int getScrollY() { return mScrollY; } 直接翻譯就可以得知
mScrollX:表示離視圖起始位置的x水平方向的偏移量
mScrollY:表示離視圖起始位置的y垂直方向的偏移量
通過getScrollX() 和getScrollY()方法獲這兄弟倆。注意:mScrollX和mScrollY指的并不是坐標,而是偏移量。
<span style="font-family:SimSun;font-size:14px;"> /** * 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(); } } } /** * 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); }</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里面移動,如果移動到了超出的地方,就不會顯示。
ScrollView.smoothScrollBy和smoothScrollTo的源碼
/** * Like {@link View#scrollBy}, but scroll smoothly instead of immediately. * * @param dx the number of pixels to scroll by on the X axis * @param dy the number of pixels to scroll by on the Y axis */ public final void smoothScrollBy(int dx, int dy) { if (getChildCount() == 0) { // Nothing to do. return; } long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll; if (duration > ANIMATED_SCROLL_GAP) { final int height = getHeight() - mPaddingBottom - mPaddingTop; //獲取部件高度 final int bottom = getChildAt(0).getHeight(); //獲取當前能看到的item高度 final int maxY = Math.max(0, bottom - height); final int scrollY = mScrollY; dy = Math.max(0, Math.min(scrollY + dy, maxY)) - scrollY; mScroller.startScroll(mScrollX, scrollY, 0, dy); postInvalidateOnAnimation(); } else { if (!mScroller.isFinished()) { mScroller.abortAnimation(); if (mFlingStrictSpan != null) { mFlingStrictSpan.finish(); mFlingStrictSpan = null; } } scrollBy(dx, dy); } mLastScroll = AnimationUtils.currentAnimationTimeMillis(); } /** * Like {@link #scrollTo}, but scroll smoothly instead of immediately. * * @param x the position where to scroll on the X axis * @param y the position where to scroll on the Y axis */ public final void smoothScrollTo(int x, int y) { smoothScrollBy(x - mScrollX, y - mScrollY); }
源碼可以看出,是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
轉載于:https://www.cnblogs.com/xiangevan/p/7818150.html
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生
總結
以上是生活随笔為你收集整理的笔记6 | 从源码理解分析mScrollX和mScrollY,scrollTo()和scrollBy(),smoothScrollTo和smoothScrollBy...的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。