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

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