scrollTo/scrollBy
- 這兩個方法都是View的內(nèi)部方法
- scrollTo和scrollBy只能改變View的內(nèi)容而不能改變View在布局中的位置。
- 移動方向與笛卡爾坐標(biāo)軸左右上下是相反的
- 在滑動過程中,View內(nèi)部的兩個屬性mscrollX和mscrollY都可以通過getScrollX和getScrollY方法獲得温数,mscrollX就是View左邊緣和View內(nèi)容左邊緣在水平方向的距離俏蛮。同理,mscrollY就是View上邊緣和View內(nèi)容的上邊緣的豎直方向的距離
Scroller
- Scroller就是一個輔助類乒躺, 用來幫助進(jìn)行彈性滑動琅束。具體使用方法如下:
//在需要改動的view中
Scroller scroller = new Scroller(mContext);
//緩慢滾動到指定位置
private void smoothScrollTo(int destX, int destY){
int scrollX = getScrollX(); //獲取當(dāng)前的mscrollX
int scrolloY = getScrollY(); //獲取當(dāng)前的mscrollY
int deltaX = destX - scrollX;
int deltaY = destY - scrollY;
mScroller.startScroll(scrollX, scrollY , deltaX, deltaY,1000);
invalidate();
}
@override
public void computeScroll(){
if ( mScroller.computeScrolljOffset()){
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
上面的代碼就是如何在自定義的View中添加彈性滑動的效果扭屁。在自定義的View初始化時(shí),定義一個Scroller涩禀,然后自己添加一個private void smoothScrollTo()
這樣一個私有方法料滥,用來被調(diào)用來執(zhí)行滑動效果的。public void computeScroll()
方法在view中本是一個空實(shí)現(xiàn)的方法艾船,這個方法在view重繪時(shí)葵腹,draw方法中會被調(diào)用。那上面的代碼整個邏輯流程是什么呢丽声?讓我們繼續(xù)往下看。
- Scroller的源碼學(xué)習(xí)
在smoothScrollTo(int destX, int destY)
方法中觉义,整個邏輯流程如下:
- 我們首先利用view的getScrollX方法和getScrollY方法獲取到現(xiàn)在view與其內(nèi)容的偏移距離雁社,
- 接著根據(jù)目標(biāo)偏移距離和當(dāng)前偏移距離的差值,得到這次目前需要進(jìn)行得分位移
- 執(zhí)行
mScroller.startScroll()
方法晒骇,輸入?yún)?shù)是當(dāng)前X霉撵,Y方向的偏移距離,目標(biāo)的偏移距離洪囤,位移時(shí)間徒坡。下面介紹下mScroller.startScroll()
方法的源碼。主要功能是保存?zhèn)鬟f的幾個參數(shù)瘤缩。
public void startScroll(int startX, int startY,int dx,int dy,int duration){
mMode = SCROLL_MODE;
mFinished = false;
mDurarion = duration;
mStartTime = AnimationUtilesd.currentAnimationTimeMilllis();
mStartX = startX;
mStartY = startY;
mFinalX = startX + dx;
mFinalY = startY + dy;
mDeltaX = dx;
mDeltaY = dy;
mDurationReciprocal = 1.0f /(float) mDuration;
}
- 調(diào)用
invalidate()
會導(dǎo)致該View重繪喇完,View在draw()方法中會調(diào)用computeScroll()
方法。 - 在
computeScroll()
方法剥啤,先調(diào)用mScroller.computeScrollOffset()
方法锦溪,并判斷其返回值不脯。該方法的主要功能就是根據(jù)開始的坐標(biāo)位移,目的坐標(biāo)位移刻诊,當(dāng)前的時(shí)間防楷,總時(shí)間來確定此時(shí)此刻的位移X Y應(yīng)該是多少,并賦給mCurrX和mCurrY则涯。public boolean computeScrollOffset(){ ... int timePassed = (int) (AnimationUtils.currentAnimationTimeMills() - mStartTime); if (timePassed < mDuration) { switch(mMode) { case SCROLL_MODE: final float x = mInterpolartor.getInterpolation(timePassed * mDurationReciprocal); mCurrX = mStartX + Math.round(x * mDeltaX); mCurrY = mStartY + Math.round(x * mDeltaY); break; ...... } } return true; }
- 在
computeScrollOffset()
執(zhí)行完后复局,在computeScroll
方法中,使用scrollTo
方法位移到剛剛計(jì)算出的mCurrX粟判,mCurrY的位置上亿昏,然后調(diào)用postInvalidate()
方法,再次要求重繪浮入,再次調(diào)用draw
方法龙优,從而再次執(zhí)行computeScroll( )
方法讓,從而能夠繪制出不同時(shí)間在不同位置出現(xiàn)的移動畫面事秀。scrollTo(mScroller.getCurrX(),mScroller.getCurrY()); postInvalidate();