不壓縮加載大圖,滑動查看,具有fling效果

參考博客,http://blog.csdn.net/lmj623565791/article/details/49300989 


public class LargeImageView extends View implements View.OnTouchListener,GestureDetector.OnGestureListener {
    private BitmapRegionDecoder mDecoder;
    /**
     * 圖片的寬度和高度
     */
    private int mImageWidth, mImageHeight;
    /**
     * 繪製的區域
     */
    private volatile Rect mRect = new Rect();


    private GestureDetector mRealDetector;

    private ValueAnimator mValueAnimator;


    private static final BitmapFactory.Options options = new BitmapFactory.Options();

    static {
        options.inPreferredConfig = Bitmap.Config.RGB_565;
    }

    private int lastY;


    public void setInputStream(InputStream is) {
        try {
            mDecoder = BitmapRegionDecoder.newInstance(is, false);
            BitmapFactory.Options tmpOptions = new BitmapFactory.Options();
            // Grab the bounds for the scene dimensions
            tmpOptions.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(is, null, tmpOptions);
            mImageWidth = /*tmpOptions.outWidth*/mDecoder.getWidth();
            mImageHeight = /*tmpOptions.outHeight*/mDecoder.getHeight();

            requestLayout();
            invalidate();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (is != null)
                    is.close();
            } catch (Exception e) {
            }
        }
    }


    public void init() {
        mValueAnimator = new ValueAnimator();
        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int animatedValue = (int) valueAnimator.getAnimatedValue();
                if (animatedValue > mImageHeight)
                    valueAnimator.cancel();

                int dy = animatedValue - lastY;
                mRect.offset(0,dy);
                checkHeight();
                invalidate();
                lastY = animatedValue;
            }
        });
        mRealDetector = new GestureDetector(this);
        setOnTouchListener(this);

    }


    private void checkWidth() {
        Rect rect = mRect;
        int imageWidth = mImageWidth;
        int imageHeight = mImageHeight;

        if (rect.right > imageWidth) {
            rect.right = imageWidth;
            rect.left = imageWidth - getWidth();
        }

        if (rect.left < 0) {
            rect.left = 0;
            rect.right = getWidth();
        }
    }


    private void checkHeight() {

        Rect rect = mRect;
        int imageWidth = mImageWidth;
        int imageHeight = mImageHeight;

        if (rect.bottom > imageHeight) {
            rect.bottom = imageHeight;
            rect.top = imageHeight - getHeight();
        }

        if (rect.top < 0) {
            rect.top = 0;
            rect.bottom = getHeight();
        }
    }


    public LargeImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Bitmap bm = mDecoder.decodeRegion(mRect, options);
        canvas.drawBitmap(bm, 0, 0, null);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int width = getMeasuredWidth();
        int height = getMeasuredHeight();

        int imageWidth = mImageWidth;
        int imageHeight = mImageHeight;

        //默認直接顯示圖片的中心區域,可以自己去調節
        mRect.left = imageWidth / 2 - width / 2;
//        mRect.top = imageHeight / 2 - height / 2;
        mRect.top = 0;
        mRect.right = mRect.left + width;
//        mRect.bottom = mRect.top + height;
        mRect.bottom = height;

    }


    @Override
    public boolean onDown(MotionEvent motionEvent) {
        if (null != mValueAnimator)
            mValueAnimator.cancel();
        return false;
    }

    @Override
    public void onShowPress(MotionEvent motionEvent) {

    }

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

    @Override
    public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float distanceX, float distanceY) {
        int moveX = (int) (distanceX+0.5f);
        int moveY = (int) (distanceY+0.5f);

        if (mImageWidth > getWidth()) {
            mRect.offset(moveX, 0);
            checkWidth();
            invalidate();
        }
        if (mImageHeight > getHeight()) {
            mRect.offset(0, moveY);
            checkHeight();
            invalidate();
        }
        return false;
    }

    @Override
    public void onLongPress(MotionEvent motionEvent) {

    }

    @Override
    public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float speedX, float speedY) {
        if (mImageHeight > getHeight()) {
            //加速度 a = -4000/s   ,time = speedY/ a , flingDy = (speedY + 0) /2 * t,speedY最大值是-8000 ~ 8000
            float a = 2700;
            int time = (int) Math.abs(speedY/a*1000);//乘以1000變成毫秒
            int flingDy = -(int) (speedY/2*time/1000);//speed是以秒爲單位的所以要除1000

            lastY = (int) motionEvent1.getY();
            mValueAnimator.setIntValues((int) motionEvent1.getY(), (int) motionEvent1.getY()+flingDy);
            mValueAnimator.setInterpolator(new DecelerateInterpolator(20f));
            mValueAnimator.setDuration(time*10);
            mValueAnimator.start();

        }
        return false;
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        return mRealDetector.onTouchEvent(motionEvent);
    }

}

使用:

<xxx.xxx.xxx.LargeImageView
            android:id="@+id/largeImage"
            android:focusable="true"
            android:clickable="true"
            android:background="@color/blue_33a6ec"
            android:layout_marginRight="20dp"
            android:layout_marginTop="20dp"
            android:layout_marginLeft="20dp"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
try {
            largeImage.setInputStream(new FileInputStream(filePath));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

 

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