1、记录下学到的Android加载长图写法以备后用

首先准备一张长图。这里把图片先放到项目的 assets文件夹下:命名为big.png

然后开始自定义显示长图的view :BigView

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;public class BigView extends View implements GestureDetector.OnGestureListener,View.OnTouchListener{    private Scroller mScroller;    private Rect mRect;    private BitmapFactory.Options mOptions;    private GestureDetector mGresureDetector;    private int mImageWight,mImageHeight;    private BitmapRegionDecoder mDecoder;    private int mViewWidth,mViewHeight;    private float mScale;    private Bitmap bitmap;    public BigView(Context context) {        this(context,null,0);    }    public BigView(Context context, @Nullable AttributeSet attrs) {        this(context, attrs,0);    }    public BigView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        //指定区域        mRect = new Rect();        //需要复用        mOptions = new BitmapFactory.Options();        //手势识别类        mGresureDetector = new GestureDetector(context,this);        //设置onTouchListener        setOnTouchListener(this);        //滑动帮助        mScroller = new Scroller(context);    }    /**     * 由使用者输入一张图片     * @param is     * @return     */    public void setImage(InputStream is){        //先读取原图片的信息  宽、高        mOptions.inJustDecodeBounds = true;        BitmapFactory.decodeStream(is,null,mOptions);        mImageWight = mOptions.outWidth;        mImageHeight = mOptions.outHeight;        //开启复用        mOptions.inMutable = true;        //设置格式成RBG_565,因为565 存储像素点占用内存小,一个像素点只需要两个字节        mOptions.inPreferredConfig = Bitmap.Config.RGB_565;        mOptions.inJustDecodeBounds = false;        //创建一个区域解码器        try {            mDecoder = BitmapRegionDecoder.newInstance(is,false);        } catch (IOException e) {            e.printStackTrace();        }        requestLayout();    }    /**     * 在测量的时候把我们需要的内存区域获取到  存入到mRect中     * @param     * @return     */    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        //获取测量的view的大小        mViewWidth = getMeasuredWidth();        mViewHeight = getMeasuredHeight();        //如果解码器拿不到,表示没有设置过要显示的图片        if (null == mDecoder){            return;        }        //确定要加载的图片的区域        mRect.left = 0;        mRect.top = 0;        mRect.right = mImageWight;        //获取一个缩放比例        mScale = mViewWidth / (float)mImageWight;        //高度就根据缩放比进行获取        mRect.bottom = (int)(mViewHeight/mScale);    }    /**     * 画出内容     * @param     * @return     */    @Override    protected void onDraw(Canvas canvas){        super.onDraw(canvas);        //如果解码器拿不到,表示没有设置过要显示的图片        if (null == mDecoder){            return;        }        //复用上一张bitmao        mOptions.inBitmap = bitmap;        //解码指定区域        bitmap = mDecoder.decodeRegion(mRect,mOptions);        //把得到的矩阵大小的内存进行缩放        Matrix matrix = new Matrix();        matrix.setScale(mScale,mScale);        //画出来        canvas.drawBitmap(bitmap,matrix,null);    }    /**     * 手按下的回调     * @param e     * @return     */    @Override    public boolean onDown(MotionEvent e) {        //如果移动还没有停止,强制停止        if (!mScroller.isFinished()){            mScroller.forceFinished(true);        }        //继续接受后续事件        return true;    }    /**     *     * @param e1 手势按下去的事件   开始获取坐标     * @param e2 当前手势事件   获取当前坐标     * @param distanceX  x方向移动的距离     * @param distanceY  y方向移动的距离     * @return     */    @Override    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {        //上下移动的时候,需要改变显示的区域  改mRect        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;    }    /**     * 处理惯性问题     * @param e1     * @param e2     * @param velocityX  每秒移动的x点     * @param velocityY     * @return     */    @Override    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {        //做计算  -velocityY  正负号问题,相反的        // ( 按下手指不拿开,屏幕跟着手势方向,若松开,方向则向相反方向滑动 ) 故 使用 负值才能正常使用        mScroller.fling(0,mRect.top,0, (int) -velocityY,0,0,0,                mImageHeight-(int)(mViewHeight/mScale));        return false;    }    /**     * 使用上一个接口的计算结果     */    @Override    public void computeScroll() {        if (mScroller.isFinished()){            return;        }        //true 表示当前滑动还没有结束        if (mScroller.computeScrollOffset()){            mRect.top = mScroller.getCurrY();            mRect.bottom = mRect.top+(int)(mViewHeight/mScale);            invalidate();        }    }    @Override    public void onShowPress(MotionEvent e) {    }    @Override    public boolean onSingleTapUp(MotionEvent e) {        return false;    }    @Override    public void onLongPress(MotionEvent e) {    }    @Override    public boolean onTouch(View v, MotionEvent event) {        //交给手势处理        return mGresureDetector.onTouchEvent(event);    }}

自定义view写完后,在要显示的布局中引入这个bigview控件,这个就不写了,放到布局就行了

下面在activity中展示:

public class BigViewActivity extends AppCompatActivity {    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.bigview_layout);        BigView bigView = findViewById(R.id.bigview);        InputStream is = null;        try {            //加载图片            is = getAssets().open("big.png");            bigView.setImage(is);        }catch (Exception e){            e.printStackTrace();        }finally {            if (is != null){                try {                    is.close();                } catch (IOException e) {                    e.printStackTrace();                }            }        }    }}

好了这些就行了,运行就可以看到加载长图,手动上下滑动浏览大图了

更多相关文章

  1. AndroidQ 系统自带文件选择器
  2. Android(安卓)Post请求SQL数据库
  3. android Launcher之获取安装的app列表的两种方法
  4. Android(安卓)4.4从图库选择图片,获取图片路径并裁剪
  5. Android系列之SQLite与Android(安卓)Studio的数据交互
  6. android获取本地图片或拍照图片
  7. Android(安卓)获取屏幕的多种宽高信息的示例代码
  8. android 获得手机号相关
  9. Android(安卓)获取按钮Button的高度、宽度、坐标

随机推荐

  1. Android 四大组件Broadcast
  2. Android Robotium搭建环境测试微信
  3. 【Android】点击应用进而打开base.apk的
  4. Android 遇坑【2】 - ScrollView 嵌套 Li
  5. Android 关闭虚拟按钮、底部导航条
  6. Android 开发环境搭建9传送帖)
  7. Android获取手机短信和通话记录及通讯录
  8. android PopupWindow简单例子
  9. Android(安卓)三种菜单(Menu)的实现
  10. [ ]在Android系统上使用busybox——最简