安卓處理慣性滑動的類是 OverScroller ,觸發(fā) fling 后 ( GestureDetector ),需多次調(diào)用其computeScrollOffset方法進行相關(guān)的計算:
if(flingScroller.computeScrollOffset()){
int cfx = flingScroller.getCurrX();
int cfy = flingScroller.getCurrY();
//CMN.Log("fling...", cfx - mLastFlingX, cfy - mLastFlingY, flingScroller.getCurrVelocity());
float dx = cfx - mLastFlingX;
float dy = cfy - mLastFlingY;
// 用 dx、dy 更新視圖
} else {
// 慣性滑動結(jié)束
}
那么在哪里調(diào)用 OverScroller 呢,之前我以為是在 runnable 中,然后循環(huán)調(diào)用直至滑動結(jié)束。
private Runnable flingRunnable = new Runnable() {
@Override
public void run() {
viewPoster.removeCallbacks(this);
if(flingScroller.computeScrollOffset()){
...
invalidate();
post(this); // 循環(huán)調(diào)用
} else {
...
}
}
}
這樣處理,在原本的 subsmapling-scale-imagview 中顯示圖片還好,可是在這個項目中,PDF渲染的高清鋪塊稍微多一點,就有明顯的卡頓現(xiàn)象。
蹊蹺的是,卡頓僅發(fā)生在慣性滑動的過程中,單、雙指移動,移動得再快也不卡,這是為什么呢?
觀察同類項目 AndroidPdfViewer ,卻沒有這個問題。
原來,AndroidPdfViewer 并未使用循環(huán)post的方法,而是復寫了 View.computeScroll 方法,在這個方法中處理 fling。
OverScroller 需與 computeScroll 配套使用,而 computeScroll 似乎是在繪制時自動回調(diào)的。這樣一來果然消除了 fling 時的卡頓,效果拔群,順暢無比,秒殺靜讀天下、ezpdf reader 等經(jīng)典應(yīng)用。
{
// post(this); // 循環(huán)調(diào)用
...
}
@Override
public void computeScroll() {
super.computeScroll();
flingRunnable.run();
}