Android开发大长图加载


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Scroller;

import java.io.IOException;
import java.io.InputStream;

/**
 * Created by yly on 2019/9/25.
 */

public class BigView extends View implements GestureDetector.OnGestureListener,View.OnTouchListener{
    private Scroller mScroller;
    private GestureDetector mGesture;
    private BitmapFactory.Options mOptions;
    private Rect mRect;
    private int mImageWidth;
    private int mImageHeight;
    private BitmapRegionDecoder mDecode;
    private int mViewWidth;
    private int mViewHeight;
    private int mScale;
    private Bitmap mBitmap;

    public BigView(Context context) {
        this(context,null);
    }

    public BigView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public BigView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        //设置BitView所需要的一些成员变量
        mRect=new Rect();
        //内存复用
        mOptions=new BitmapFactory.Options();
        //手势识别
        mGesture=new GestureDetector(context,this);
        mScroller=new Scroller(context);

        setOnTouchListener(this);
    }

    //设置图片得到图片信息
    public void setImage(InputStream is){
        mOptions.inJustDecodeBounds=false;
        BitmapFactory.decodeStream(is,null,mOptions);

        //获取宽高,不能把整张图片加载进去
        mImageWidth=mOptions.outWidth;
        mImageHeight=mOptions.outHeight;
        //开启复用
        mOptions.inMutable=true;
        //设置RGB,//比4个8大一倍,把透明通道给去掉了当然565质量也会降低,还是要根据自己的需求
        //4个8和565用的是最多的
        mOptions.inPreferredConfig= Bitmap.Config.RGB_565;
        mOptions.inJustDecodeBounds=true;

        //区域解码器
        try {
            mDecode= BitmapRegionDecoder.newInstance(is,false);
        } catch (IOException e) {
            e.printStackTrace();
        }

        requestLayout();


    }
    //3,开始测量,等比例的缩放,必须要知道手机的宽高,得到View的宽高,要加载的图片到底要是什么样子

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

        //得到View的大小
        mViewWidth=getMeasuredWidth();
        mViewHeight=getMeasuredHeight();
        //确定加载图片的区域,没有缩放图片

        mRect.left=0;
        mRect.top=0;

        mRect.right=getMeasuredWidth();
        //计算缩放因子
        mScale=mViewWidth/mImageWidth;
        mRect.bottom=mViewHeight/mScale;





    }


    //4,画出具体内容

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //判断解码器是不是为空

        if (mDecode==null){
            //如果解码器为空表示没有设置过图片
            return ;
        }

        //内存复用

        mOptions.inBitmap= mBitmap;
        //指定解码的区域
        mBitmap=mDecode.decodeRegion(mRect,mOptions);
        Matrix matrix=new Matrix();
        matrix.setScale(mScale,mScale);
        canvas.drawBitmap(mBitmap,matrix,null);


    }

    //第五步,处理手势,这时已经可以把绿色显示,处理点击时间
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        //直接交给手势处理
        return mGesture.onTouchEvent(event);

    }

    @Override
    public boolean onDown(MotionEvent e) {
        //滑动的时候点击停下俩
        if (!mScroller.isFinished()){
            mScroller.forceFinished(true);
        }
        return true;
    }

    //处理滑动事件,第一第二参数手指按下获取当前坐标,第三第四表示xy周移动距离
    @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-(mViewHeight/mScale);
        }

        if (mRect.top<0){

            mRect.top=0;
            mRect.bottom=mViewHeight/mScale;
        }

        invalidate();

        return false;
    }

    //第八步,处理惯性问题
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

        mScroller.fling(0,mRect.top,0, (int) -velocityY,0,0,0,mImageHeight-mViewHeight/mScale);

        return false;
    }

    //第九步,处理计算结果


    @Override
    public void computeScroll() {
        super.computeScroll();
        if (mScroller.isFinished()){
            return;
        }

        //滑动没有结束就要处理
        if (mScroller.computeScrollOffset()){

            //就要去加载
            mRect.top=mScroller.getCurrY();
            mRect.bottom=mRect.top+mViewHeight/mScale;
            invalidate();
        }

    }

    @Override
    public void onShowPress(MotionEvent e) {

    }

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


    @Override
    public void onLongPress(MotionEvent e) {

    }



}

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;

import com.example.demoproject.loadbigImage.BigView;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    private static List<String> mList;
    private Handler handler;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        BigView bigView = findViewById(R.id.bigView);

        try {
            InputStream in = getAssets().open("big.png");

            bigView.setImage(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
发布了75 篇原创文章 · 获赞 31 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/yaoyaoyao_123/article/details/101389107