安卓大圖加載

項(xiàng)目中需要用到家在大圖,圖片長度大概40000像素,直接加載會(huì)拋異常,所以準(zhǔn)備自己寫一個(gè)大圖的加載view,
需要實(shí)現(xiàn)的功能包括
1.加載出大圖
2.可以滑動(dòng),需要處理邊界
3.支持手勢的縮放

1加載大圖

這里主要使用了 BitmapRegionDecoder 這個(gè)類,初始化需要一個(gè)bitmap的inputStream, 可以根據(jù)添加的矩形區(qū)域,獲取到當(dāng)前bitmap在該區(qū)域的bitmap,然后繪制到view中,
而Bitmap的獲取,需要注意要復(fù)用bitmap內(nèi)存,每次都不需要獲取新的內(nèi)存空間,避免內(nèi)存的分配與回收

需要注意的是:
api19以前格式只為jpg,png,同等寬高,inSampleSize為1才能復(fù)用
api19以后復(fù)用復(fù)用的bitmap的內(nèi)存 必須大于等于需要申請的bitmap的內(nèi)存

主要代碼:

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

滑動(dòng),普通手勢處理邊界;慣性手勢;雙擊縮放

滑動(dòng)主要是使用 GestureDetector ,

OnGestureListener,Scroller
//通過Scroller可以實(shí)現(xiàn)View在一定時(shí)間間隔內(nèi)的彈性滑動(dòng)
基本使用

//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  就是開始事件,手指按下去,獲取坐標(biāo)
    *e2  當(dāng)前事件;
    */
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
      //3  拿到拖動(dòng)事件,并修改矩形位置,重新繪制
       // 上下移動(dòng)的時(shí)候,mRect需要改變顯示區(qū)域
        mRect.offset((int)distanceX,(int)distanceY);
        // 移動(dòng)時(shí),處理到達(dá)頂部和底部的情況
        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  在手抬起來的時(shí)候回調(diào)的
     * @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;
    }

// 處理結(jié)果  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);
        // 移動(dòng)時(shí),處理到達(dá)頂部和底部的情況
        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:處理點(diǎn)擊事件
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        // 直接將時(shí)間傳遞給手勢事件處理
        mScaleGestureDetector.onTouchEvent(event);
        return true;
    }

// 處理縮放的回調(diào)事件
    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;
        }
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 7.1 壓縮圖片 一、基礎(chǔ)知識(shí) 1、圖片的格式 jpg:最常見的圖片格式。色彩還原度比較好,可以支持適當(dāng)壓縮后保持...
    AndroidMaster閱讀 2,706評(píng)論 0 13
  • 一直以來Bitmap在Android中的處理都是非常棘手的。如果我們直接將一個(gè)完整分辨率的圖片加載到內(nèi)存中它會(huì)占用...
    godliness閱讀 1,798評(píng)論 0 13
  • 簡介 這個(gè)項(xiàng)目是一個(gè)用于Android預(yù)覽大圖片的圖片顯示庫,可實(shí)現(xiàn)原始圖片高清顯示,專門針對大圖片做了很多優(yōu)化,...
    不具名家閱讀 8,984評(píng)論 10 39
  • 親愛的小壞壞, 你好呀! 今天你的定型枕終于干啦,這是小雨阿姨推薦的,據(jù)說子彈哥哥用了效果很好喲。馬上給你用上,果...
    安安媽媽_小竹子閱讀 328評(píng)論 0 0
  • 今年開始了租房和工作的生活,也開始學(xué)會(huì)平衡生活與工作,忙碌之余不忘給自己一點(diǎn)放松的時(shí)間。作為一個(gè)吃貨,我開始學(xué)著做...
    愛吃愛花愛生活的UX人閱讀 1,586評(píng)論 2 3

友情鏈接更多精彩內(nèi)容