Bitmap长图加载

作者: Shimmer_ | 来源:发表于2021-06-01 19:42 被阅读0次

    加载思路

    • 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

    相关文章

      网友评论

        本文标题:Bitmap长图加载

        本文链接:https://www.haomeiwen.com/subject/xldgsltx.html