Bitmap長圖加載

加載思路

  • BitmapRegionDecoder 根據要展示的矩形大小及長圖的流來生成Bitmap進行顯示
  • 使用自定義的View,根據用戶的操作及長圖的尺寸來實時定位要顯示的矩形大小
  • 實時更新顯示,這樣完成加載長圖的功能

重點步驟

從流中截取生成顯示的Bitmap

BitmapRegionDecoder mBitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false); // false 不共享 圖片源,這樣當外部流關閉時不影響自身操作
bitmap = mBitmapRegionDecoder.decodeRegion(mRect, mOptions);//根據區域生成Bitmap,mOptions爲加載優化設置,不影響主體功能

計算縮放顯示比例

mViewHeight = getMeasuredHeight();
mViewWidth = getMeasuredWidth();
mRect.left = 0;
mRect.top = 0;
mRect.right = mImageWidth;
// 縮放因子
mScale = mViewWidth / (float) mImageWidth;
// x * mscale = mViewHeight
mRect.bottom = (int) (mViewHeight / mScale);

響應手勢(GestureDetector)與滑動(Scroller)

@Override
public boolean onTouch(View v, MotionEvent event) {
    // 事件交給手勢處理
    return mGestureDetector.onTouchEvent(event);
}
//點擊--ACTION_DOWN
@Override
public boolean onDown(MotionEvent e) {
    // 如果滑動還沒有停止 強制停止
    if (!mScroller.isFinished()) {
        mScroller.forceFinished(true);
    }
    //繼續接收後續事件
    return true;
}
//滑動--ACTION_DOWN 多個ACTION_MOVE
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
    //改變加載圖片的區域
    mRect.offset(0, (int) distanceY);
    //滑動到底
    if (mRect.bottom > mImageHeight) {
        mRect.bottom = mImageHeight;
        mRect.top = mImageHeight - (int) (mViewHeight / mScale);
    }
    //滑動到頂
    if (mRect.top < 0) {
        mRect.top = 0;
        mRect.bottom = (int) (mViewHeight / mScale);
    }
    // 重繪
    invalidate();
    return false;
}
//快滑--ACTION_DOWN 多個ACTION_MOVE ACTION_UP
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    /**
         * startX: 滑動開始的x座標
         * velocityX: 以每秒像素爲單位測量的初始速度
         * minX: x方向滾動的最小值
         * maxX: x方向滾動的最大值
         */
    mScroller.fling(0, mRect.top, 0, (int) -velocityY, 0, 0,
                    0, mImageHeight - (int) (mViewHeight / mScale));
    return false;
}
@Override
public void computeScroll() {
    //已經計算結束 return
    if (mScroller.isFinished()) {
        return;
    }
    //true 表示當前動畫未結束
    if (mScroller.computeScrollOffset()) {
        mRect.top = mScroller.getCurrY();
        mRect.bottom = mRect.top + (int) (mViewHeight / mScale);
        invalidate();
    }
}

實現類

https://gitee.com/sj_tick/AndroidTools/blob/master/tools/src/main/java/com/sj/tools/customview/BigImageView.java

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章