android Scroller原理分析

2021-06-30 16:53:59 字數 4681 閱讀 1261

在android中,scroller是用來實現view的滑動效果。使用的步驟如下:

1. 建立scroller物件

2. 呼叫scroller.startscoller()或者fling()方法。

3. 在呼叫startscroller()或者fling()方法後呼叫invalidate(),促使view重繪

4. 重寫view的computescroll()方法。

其中view的computescroll()是在view樹draw()的時候呼叫。

scroller類中主要的成員變數有:

private

int mmode;

6566

private

int mstartx;

67private

int mstarty;

68private

int mfinalx;

69private

int mfinaly;

7071

private

int mminx;

72private

int mmaxx;

73private

int mminy;

74private

int mmaxy;

7576

private

int mcurrx;

77private

int mcurry;

78private

long mstarttime;

79private

int mduration;

80private

float mdurationreciprocal;

81private

float mdeltax;

82private

float mdeltay;

83private

boolean mfinished;

84private interpolator minterpolator;

87private

float mvelocity;

88private

float mcurrvelocity;

89private

int mdistance;

其中mmode代表scroller的模式,fling或者scroll;mstartx,mstarty代表起始的座標;mfinalx、mfinaly代表重點座標;mcurrx、mcurry代表當前座標;mdeltax、mdeltay代表需要移動的偏移量,mfinished代表是否完成;minterpolator用來計算下一次移動的位置,可以用它來控制scroller的移動效果。

在使用過程中,我們會呼叫scroller.startscroll()方法,startscroll()方法如下:

public

void

startscroll(int startx, int starty, int dx, int dy, int duration)

這個方法進行一些初始化操作,給關鍵的變數賦值。同樣fling()方法類似。

public void fling(int startx, int starty, int velocityx, int velocityy,

432int minx, int maxx, int miny, int maxy)

451 }

452453 mmode = fling_mode;

454 mfinished = false;

455456

float velocity = floatmath.sqrt(velocityx * velocityx + velocityy * velocityy);

457458 mvelocity = velocity;

459 mduration = getsplineflingduration(velocity);

460 mstarttime = animationutils.currentanimationtimemillis();

461 mstartx = startx;

462 mstarty = starty;

463464

float coeffx = velocity == 0 ? 1.0f : velocityx / velocity;

465float coeffy = velocity == 0 ? 1.0f : velocityy / velocity;

466467

double totaldistance = getsplineflingdistance(velocity);

468 mdistance = (int) (totaldistance * math.signum(velocity));

469470 mminx = minx;

471 mmaxx = maxx;

472 mminy = miny;

473 mmaxy = maxy;

474475 mfinalx = startx + (int) math.round(totaldistance * coeffx);

476// pin to mminx <= mfinalx <= mmaxx

477 mfinalx = math.min(mfinalx, mmaxx);

478 mfinalx = math.max(mfinalx, mminx);

479480 mfinaly = starty + (int) math.round(totaldistance * coeffy);

481// pin to mminy <= mfinaly <= mmaxy

482 mfinaly = math.min(mfinaly, mmaxy);

483 mfinaly = math.max(mfinaly, mminy);

484 }

接著呼叫invalidate()導致view重繪,呼叫computescroll(), 在computescroll()方法裡面需要呼叫scroller.computescrolloffset()方法,這個方法判斷滾動是否結束,

public

boolean

computescrolloffset()

309310

int timepassed = (int)(animationutils.currentanimationtimemillis() - mstarttime);

311312

if (timepassed < mduration)

338339 mcurrvelocity = velocitycoef * mdistance / mduration * 1000.0f;

340341 mcurrx = mstartx + math.round(distancecoef * (mfinalx - mstartx));

342// pin to mminx <= mcurrx <= mmaxx

343 mcurrx = math.min(mcurrx, mmaxx);

344 mcurrx = math.max(mcurrx, mminx);

345346 mcurry = mstarty + math.round(distancecoef * (mfinaly - mstarty));

347// pin to mminy <= mcurry <= mmaxy

348 mcurry = math.min(mcurry, mmaxy);

349 mcurry = math.max(mcurry, mminy);

350351

if (mcurrx == mfinalx && mcurry == mfinaly)

354355

break;

356 }

357 }

358else

363return

true;

364 }

在這個方法裡會去判斷當前mode型別,如果是滾動型別,計算乙個x的權值,給mcurrx和mcurry賦值,然後再呼叫view.scrollby()或者view.scrollto()方法來實現滾動。如果是fling型別,類似滾動型別,根據速度和時間計算偏移量,賦值mcurrx, mcurry,再呼叫view.scrollby()或者view.scrollto()實現滾動,接著呼叫invalidate(),繼續重繪,從而實現滾動效果。

在scroller類中有乙個成員變數interpolator,這個變數是用來描述滾動過程中的動畫效果。他的呼叫時在computescrolloffset()中,通過interpolator.getinterpolation()來控制移動時的偏移量。如果interpolator為null,則通過scroll內部viscousfluid()來控制偏移量。

Android Scroller學習筆記

今天看了一篇郭霖大神的關於scroller的文章,在這裡做個筆記,以方便學習。原文見鏈結android scroller完全解析,關於scroller你所需知道的一切 一,什麼是scroller scroller是乙個專門用來處理滾動效果的工具類,我們直接使用scroller的場景並不多,但是許多我...

Android Scroller簡單用法

android裡scroller類是為了實現view平滑滾動的乙個helper類。通常在自定義的view時使用,在view中定義乙個私有成員mscroller new scroller context 設定mscroller滾動的位置時,並不會導致view的滾動,通常是用mscroller記錄 計算...

ConcurrentHashMap原理分析

hashtable是乙個執行緒安全的類,它使用synchronized來鎖住整張hash表來實現執行緒安全,即每次鎖住整張表讓執行緒獨佔。concurrenthashmap允許多個修改操作併發進行,其關鍵在於使用了鎖分離技術。它使用了多個鎖來控制對hash表的不同部分進行的修改。concurrent...