美文网首页
安卓大图加载

安卓大图加载

作者: 奔波儿灞_q | 来源:发表于2019-12-27 15:40 被阅读0次

项目中需要用到家在大图,图片长度大概40000像素,直接加载会抛异常,所以准备自己写一个大图的加载view,
需要实现的功能包括
1.加载出大图
2.可以滑动,需要处理边界
3.支持手势的缩放

1加载大图

这里主要使用了 BitmapRegionDecoder 这个类,初始化需要一个bitmap的inputStream, 可以根据添加的矩形区域,获取到当前bitmap在该区域的bitmap,然后绘制到view中,
而Bitmap的获取,需要注意要复用bitmap内存,每次都不需要获取新的内存空间,避免内存的分配与回收

需要注意的是:
api19以前格式只为jpg,png,同等宽高,inSampleSize为1才能复用
api19以后复用复用的bitmap的内存 必须大于等于需要申请的bitmap的内存

主要代码:

 try {
        mBitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false);
     } catch (IOException e) {
            e.printStackTrace();
     }
//这里mRect是需要截取的矩形区域,mBitmap是截取到的bitmap
mBitmap = mBitmapRegionDecoder.decodeRegion(mRect, mOptions);
canvas.drawBitmap(mBitmap, matrix, null);

滑动,普通手势处理边界;惯性手势;双击缩放

滑动主要是使用 GestureDetector ,

OnGestureListener,Scroller
//通过Scroller可以实现View在一定时间间隔内的弹性滑动
基本使用

//1.
mGesture = new GestureDetector(context,OnGestureListener);
 @Override
 public boolean onTouch(View v, MotionEvent event) {
        // 2,直接将事件传递给手势事件处理
      mGesture.onTouchEvent(event);
      return true;
}
//OnGestureListener中
 @Override
    public boolean onDown(MotionEvent e) {
        return false;
    }

    @Override
    public void onShowPress(MotionEvent e) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }

    /**
    *e1  就是开始事件,手指按下去,获取坐标
    *e2  当前事件;
    */
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
      //3  拿到拖动事件,并修改矩形位置,重新绘制
       // 上下移动的时候,mRect需要改变显示区域
        mRect.offset((int)distanceX,(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);
        }
        if(mRect.right > mImageWidth){
            mRect.right = mImageWidth;
            mRect.left = mImageWidth-(int)(mViewWidth/mScale);
        }
        if(mRect.left < 0 ){
            mRect.left = 0;
            mRect.right = (int)(mViewWidth/mScale);
        }
        invalidate();
        return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {

    }

    /**
     * @param e1  在手抬起来的时候回调的
     * @param e2
     * @param velocityX x方向速度;
     * @param velocityY y方向速度;
     * @return
     */
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//将惯性事件交给mScroller
        mScroller.fling(mRect.left, mRect.top,
                (int) -velocityX, (int) -velocityY,
                0, viewWidth,
                0, viewHeight
        );
        return false;
    }

// 处理结果  view的方法;
    @Override
    public void computeScroll() {
        if(mScroller.isFinished()){
            return;
        }
        if(mScroller.computeScrollOffset()){
            mRect.top = mScroller.getCurrY();
            mRect.bottom = mRect.top+(int)(mViewHeight/mScale);
            invalidate();
        }
    }

手势可以添加双击手势
OnDoubleTapListener,(双击手势)

 mGestureDetector.setOnDoubleTapListener(this);
 @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onDoubleTap(MotionEvent e) {
        // 双击事件
        if(mScale < originalScale*1.5){
            mScale = originalScale*3;
        }else{
            mScale = originalScale;
        }
        mRect.right = mRect.left+(int)(mViewWidth/mScale);
        mRect.bottom = mRect.top+(int)(mViewHeight/mScale);
        // 移动时,处理到达顶部和底部的情况
        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);
        }
        if(mRect.right > mImageWidth){
            mRect.right = mImageWidth;
            mRect.left = mImageWidth-(int)(mViewWidth/mScale);
        }
        if(mRect.left < 0 ){
            mRect.left = 0;
            mRect.right = (int)(mViewWidth/mScale);
        }
        invalidate();
        return true;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent e) {
        return false;
    }

3.缩放手势

mScaleGestureDetector = new ScaleGestureDetector(context,new ScaleGesture());

// 5:处理点击事件
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // 直接将时间传递给手势事件处理
        mScaleGestureDetector.onTouchEvent(event);
        return true;
    }

// 处理缩放的回调事件
    class ScaleGesture extends ScaleGestureDetector.SimpleOnScaleGestureListener{
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            float scale = mScale;

            scale += detector.getScaleFactor() -1;
            if(scale <= originalScale){
                scale = originalScale;
            }else if(scale > originalScale*5){
                scale = originalScale*5;
            }
            mRect.right = mRect.left + (int)(mViewWidth/scale);
            mRect.bottom = mRect.top + (int)(mViewHeight/scale);
            mScale = scale;
            invalidate();
            return true;
        }
    }

相关文章

  • 安卓大图加载

    项目中需要用到家在大图,图片长度大概40000像素,直接加载会抛异常,所以准备自己写一个大图的加载view,需要实...

  • Android加载大图长图方案简析

    本文只是简要分析安卓端自带压缩与加载方案 1,高效加载加载大图 展示高分辨率图片的时候,最好先将图片进行压缩。 B...

  • 安卓类加载机制

    热修复、插件化很多技术都是基于安卓类加载机制实现,所以对安卓类加载机制了解很有必要

  • 微信webview开发的那些坑

    安卓和ios不同的视频播放特性 安卓刷新无效,缓存 图片预加载

  • 2018-11-07

    Android 加载长图片的自定义控件!解决安卓加载长图出现解码失败导致显示空白的问题! 关于解决超大图片超过bi...

  • 2018-09-04

    关于安卓加载不同形式values文件夹优先级的探究 一.导入 我们大家都知道,安卓在加载values文件的时候。会...

  • 安卓自定义View-画圆

    效果图 代码 安卓开发入门教程系列汇总 安卓发展历程及前景 安卓发展历程 安卓开发前景展望 初探安卓 安装开发工...

  • 安卓动画样例-圆环变多变少

    效果图 代码 安卓开发入门教程系列汇总 安卓发展历程及前景 安卓发展历程 安卓开发前景展望 初探安卓 安装开发工...

  • 安卓动画样例-放大缩小

    效果图 实现代码 安卓开发入门教程系列汇总 安卓发展历程及前景 安卓发展历程 安卓开发前景展望 初探安卓 安装开...

  • Android温故而知新 - ClassLoader

    安卓插件化越来越流行,其中用到的技术不外乎加载外部的资源和加载外部的代码,关于加载外部资源我之前写过一篇文章《安卓...

网友评论

      本文标题:安卓大图加载

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