安卓处理惯性滑动的类是 OverScroller ,触发 fling 后 ( GestureDetector ),需多次调用其computeScrollOffset
方法进行相关的计算:
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 {
// 惯性滑动结束
}
那么在哪里调用 OverScroller 呢,之前我以为是在 runnable 中,然后循环调用直至滑动结束。
private Runnable flingRunnable = new Runnable() {
@Override
public void run() {
viewPoster.removeCallbacks(this);
if(flingScroller.computeScrollOffset()){
...
invalidate();
post(this); // 循环调用
} else {
...
}
}
}
这样处理,在原本的 subsmapling-scale-imagview 中显示图片还好,可是在这个项目中,PDF渲染的高清铺块稍微多一点,就有明显的卡顿现象。
蹊跷的是,卡顿仅发生在惯性滑动的过程中,单、双指移动,移动得再快也不卡,这是为什么呢?
观察同类项目 AndroidPdfViewer ,却没有这个问题。
原来,AndroidPdfViewer 并未使用循环post的方法,而是复写了 View.computeScroll 方法,在这个方法中处理 fling。
OverScroller 需与 computeScroll 配套使用,而 computeScroll 似乎是在绘制时自动回调的。这样一来果然消除了 fling 时的卡顿,效果拔群,顺畅无比,秒杀静读天下、ezpdf reader 等经典应用。
{
// post(this); // 循环调用
...
}
@Override
public void computeScroll() {
super.computeScroll();
flingRunnable.run();
}
网友评论