好久好久没有学习了,每天在王者农药里浸泡着,终于上了王者段位之后,心里空空如也!!是时候开始学习了,向高级进发!!!

学习感想:

在学习之前,不使用第三方框架的情况下,会有:哇,这咋搞,直接OOM呀!一脸萌币
学习之后,我去,就这么简单???

正文开始

总结一下很简单了:
原理:将图片分块加载,滑到哪一块,加载哪一块区域。
大致步骤: 声明 BitmapFactory.Options和Rect对象,对Options对象属性操作,获取图片信息和设置显示图片是否复用内存;对Rect对象的 left,top,right,bottom属性值操作,动态设置图片显示区域,使用构建的图片解码器获取 图片目标区域的bitmap,最终使用 cavers绘制就OK了,其他双击缩放和惯性滑动,在这个基础上拓展也很简单,是不是也有一种感觉:**,就这么简单?

实现步骤如下:
1.初始化成员变量
2.根据图片流 ,使用 BitmapFactory.Options对象 ,获取图片尺寸,
3.使用 option对象的 inMutable=true的属性,设置内存复用,
4.使用 mOptions.inPreferredConfig = Bitmap.Config.RGB_565 设置图片格式,
5.构建 图片解释器 :BitmapRegionDecoder.newInstance(bitmapInputStream, false);
6.获取屏幕尺寸,
7.声明 Rect对象,计算图片显示像素区域
8.设置 option对象的 bitmap数据,使用 cavers绘制区域图形
9.使用 手势处理类,处理滑动事件

来吧,展示

  1. 初始化成员变量、根据图片流 ,使用 BitmapFactory.Options对象 ,获取图片尺寸,
    //第一步 初始化成员变量    private void initView(Context context, AttributeSet attrs, int defStyleAttr) {        //显示区域        mRect = new Rect();        //bitmapFactory 的属性类        mOptions = new BitmapFactory.Options();        //手势识别对象        mGestureListener = new GestureDetector(context, this);        //设置点击事件        setOnTouchListener(this);        //滚动辅助类        mScroller = new Scroller(context);    }/** * 2.根据图片流 ,使用 BitmapFactory.Options对象 ,获取图片尺寸, * 3.使用 option对象的 inMutable=true的属性,设置内存复用, * 4.使用 mOptions.inPreferredConfig = Bitmap.Config.RGB_565  设置图片格式, * 5.构建 图片解释器 :BitmapRegionDecoder.newInstance(bitmapInputStream, false); */    public void setImageIs(InputStream stream) {        //只获取 图片信息,不加载到内存里,节约内存空间        mOptions.inJustDecodeBounds = true;        //解析图片流信息        BitmapFactory.decodeStream(stream, null, mOptions);        //图片宽        mImageWidth = mOptions.outWidth;        //图片高        mImageHeight = mOptions.outHeight;        //开启复用        mOptions.inMutable = true;        //设置图片格式        mOptions.inPreferredConfig = Bitmap.Config.RGB_565;        //关闭只读信息模式        mOptions.inJustDecodeBounds = false;        //声明 图片构造器        try {            mDecor = BitmapRegionDecoder.newInstance(stream, false);        } catch (IOException e) {            e.printStackTrace();        }        //刷新视图        requestLayout();    }
  1. 获取屏幕尺寸,声明 Rect对象,计算图片显示像素区域
    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        //获取屏幕尺寸信息        mWindowWidth = getMeasuredWidth();        mWindowHeight = getMeasuredHeight();        mRect.left = 0;        mRect.top = 0;        //设置显示区域        mRect.right = mImageWidth > mWindowWidth ? mWindowWidth : mImageWidth;        mRect.bottom = mImageHeight > mWindowHeight ? mWindowHeight : mImageHeight;    }
  1. 设置 option对象的 bitmap数据,使用 cavers绘制区域图形
    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        //获取屏幕尺寸信息        mWindowWidth = getMeasuredWidth();        mWindowHeight = getMeasuredHeight();        mRect.left = 0;        mRect.top = 0;        //设置显示区域        mRect.right = mImageWidth > mWindowWidth ? mWindowWidth : mImageWidth;        mRect.bottom = mImageHeight > mWindowHeight ? mWindowHeight : mImageHeight;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if (mDecor == null) {            throw new RuntimeException("还未设置图片???");        }        //设置图片  bitmap        mOptions.inBitmap = mBitmap;        mBitmap = mDecor.decodeRegion(mRect, mOptions);        Matrix matrix = new Matrix();        matrix.setScale(1f, 1f);        canvas.drawBitmap(mBitmap, matrix, null);    }
  1. 使用 手势处理接口,处理滑动事件,刷新视图
    //将 时间传递 发给 收拾处理器    @Override    public boolean onTouch(View v, MotionEvent event) {        return mGestureListener.onTouchEvent(event);    }    /** * 处理滑动事件,动态设置mRect对象的区域范围,刷新视图 */    @Override    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {        mRect.offset((int) distanceX, (int) distanceY);        if (mRect.left < 0) {            mRect.left = 0;            mRect.right = mWindowWidth;        }        if (mRect.top < 0) {            mRect.top = 0;            mRect.bottom = mWindowHeight;        }        if (mRect.right > mImageWidth) {            mRect.left = mImageWidth - mWindowWidth;            mRect.right = mImageWidth;        }        if (mRect.bottom > mImageHeight) {            mRect.top = mImageHeight - mWindowHeight;            mRect.bottom = mImageHeight;        }        invalidate();        return false;    }

整个类文件放出来:

package com.gerryrun.gerryandroiddemo.weight;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.util.AttributeSet;import android.view.GestureDetector;import android.view.MotionEvent;import android.view.View;import android.widget.Scroller;import androidx.annotation.Nullable;import java.io.IOException;import java.io.InputStream;/** * com.gerryrun.gerryandroiddemo.weight * create by GerryRun * email:gerryin@163.com * 2020-08-15  20:52 * Describe here:  大长图 加载原理(无缩放,无惯性滑动,//todo 有时间加上 缩放和惯性滑动) * steps: * 1.初始化成员变量 * 2.根据图片流 ,使用 BitmapFactory.Options对象 ,获取图片尺寸, * 3.使用 option对象的 inMutable=true的属性,设置内存复用, * 4.使用 mOptions.inPreferredConfig = Bitmap.Config.RGB_565  设置图片格式, * 5.构建 图片解释器 :BitmapRegionDecoder.newInstance(bitmapInputStream, false); * 6.获取屏幕尺寸, * 7.声明 Rect对象,计算图片显示像素区域 * 8.设置 option对象的 bitmap数据,使用 cavers绘制区域图形 * 9.使用 手势处理类,处理滑动事件 */public class BigView extends View implements View.OnTouchListener, GestureDetector.OnGestureListener {    private Rect mRect;//显示区域    private BitmapFactory.Options mOptions;    private GestureDetector mGestureListener;    private int mImageWidth, mImageHeight;    private int mWindowWidth, mWindowHeight;    private BitmapRegionDecoder mDecor;    private Bitmap mBitmap;    private Scroller mScroller;    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);        initView(context, attrs, defStyleAttr);    }    //第一步 初始化成员变量    private void initView(Context context, AttributeSet attrs, int defStyleAttr) {        //显示区域        mRect = new Rect();        //bitmapFactory 的属性类        mOptions = new BitmapFactory.Options();        //手势识别对象        mGestureListener = new GestureDetector(context, this);        //设置点击事件        setOnTouchListener(this);        //滚动辅助类        mScroller = new Scroller(context);    }    //第二步 设置图片 获取图片信息    public void setImageIs(InputStream stream) {        //只获取 图片信息,不加载到内存里,节约内存空间        mOptions.inJustDecodeBounds = true;        //解析图片流信息        BitmapFactory.decodeStream(stream, null, mOptions);        //图片宽        mImageWidth = mOptions.outWidth;        //图片高        mImageHeight = mOptions.outHeight;        //开启复用        mOptions.inMutable = true;        //设置图片格式        mOptions.inPreferredConfig = Bitmap.Config.RGB_565;        //关闭只读信息模式        mOptions.inJustDecodeBounds = false;        //声明 图片解码器        try {            mDecor = BitmapRegionDecoder.newInstance(stream, false);        } catch (IOException e) {            e.printStackTrace();        }        //刷新视图        requestLayout();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        //获取屏幕尺寸信息        mWindowWidth = getMeasuredWidth();        mWindowHeight = getMeasuredHeight();        //设置显示区域        mRect.left = 0;        mRect.top = 0;        mRect.right = mImageWidth > mWindowWidth ? mWindowWidth : mImageWidth;        mRect.bottom = mImageHeight > mWindowHeight ? mWindowHeight : mImageHeight;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //图片解码器为空,就是意味着没有设置图片        if (mDecor == null) {            throw new RuntimeException("还未设置图片???");        }        //设置图片  bitmap        mOptions.inBitmap = mBitmap;        //解码出区域 图片对象        mBitmap = mDecor.decodeRegion(mRect, mOptions);//矩阵对象        Matrix matrix = new Matrix();        //设置缩放倍数,当图片进行缩放时,计算缩放因子,设置就OK了        matrix.setScale(1f, 1f);        canvas.drawBitmap(mBitmap, matrix, null);    }    //将 时间传递 发给 收拾处理器    @Override    public boolean onTouch(View v, MotionEvent event) {        return mGestureListener.onTouchEvent(event);    }    @Override    public boolean onDown(MotionEvent e) {        if (!mScroller.isFinished()) {        //强制停止滚动            mScroller.forceFinished(true);        }        //消费点击事件        return true;    }    @Override    public void onShowPress(MotionEvent e) {    }    @Override    public boolean onSingleTapUp(MotionEvent e) {        return false;    }    @Override    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {        mRect.offset((int) distanceX, (int) distanceY);        if (mRect.left < 0) {            mRect.left = 0;            mRect.right = mWindowWidth;        }        if (mRect.top < 0) {            mRect.top = 0;            mRect.bottom = mWindowHeight;        }        if (mRect.right > mImageWidth) {            mRect.left = mImageWidth - mWindowWidth;            mRect.right = mImageWidth;        }        if (mRect.bottom > mImageHeight) {            mRect.top = mImageHeight - mWindowHeight;            mRect.bottom = mImageHeight;        }        invalidate();        return false;    }    @Override    public void onLongPress(MotionEvent e) {    }        //处理惯性滑动    @Override    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {        mScroller.fling(mRect.left, mRect.top, (int) -velocityX, (int) -velocityY, 0, mImageWidth, 0, mImageHeight);        return false;    }    @Override    public void computeScroll() {        super.computeScroll();        if (mScroller.isFinished()) {            return;        }        //滚动还没有结束        if (mScroller.computeScrollOffset()) {            mRect.left = mScroller.getCurrX();            mRect.top = mScroller.getCurrY();            mRect.right = mRect.left + mWindowWidth;            mRect.bottom = (mRect.top + mWindowHeight);            //上下 范围计算            if (mRect.bottom > mImageHeight) {                mRect.bottom = mImageHeight;                mRect.top = mImageHeight - mWindowHeight;            }            //左右 范围计算            if (mRect.right > mImageWidth) {                mRect.right = mImageWidth;                mRect.left = mImageWidth - mWindowWidth;            }            invalidate();        }    }}

**!!就这么简单???

有缘人,下面这段话是我心里的苦水,只能在这儿诉说一下

    • 学习感想:
    • 正文开始

结合老婆生产之后,家庭成员之间关系的变化情况,我在想,如果以后我生了女儿,我会不会同意我的宝贝女儿找家里同胞兄弟个数大于一个的男朋友,我觉得我不会同意,绝对不会
本人家里有个哥哥,在这么一个上有老下有小的人生阶段,我心里苦水真的不知道向谁诉说,只能打碎牙齿往肚里咽吧,也许有一天我也会崩溃的坐在大首都的某个角落大哭一场,被人拍下上了抖音、快手吧,人生不易,爱父母,爱妻儿,好好学习且行且珍惜吧,谢谢你读完了这段话,

更多相关文章

  1. [置顶] android 从资源中获取数组
  2. java/android 设计模式学习笔记(18)---中介者模式
  3. 【Android】日期拾取器、时间拾取器与菜单
  4. 2019年Android开发者常见面试题(一)
  5. Android(安卓)MediaCodec API实现的音视频编解码
  6. Android图片特效处理(像素处理)
  7. android和javaEE更完美的通信-传递对象
  8. Android中关于屏幕的三个小众知识(宽屏适配、禁止截屏和保持屏幕
  9. android 震动效果类

随机推荐

  1. android sdk setup时呈现:Failed to fetc
  2. android 画虚线、实线,画圆角矩形,一半圆角
  3. Android(安卓)NFC架构分析
  4. Android(安卓)侧滑菜单的实现
  5. 通过WifiManager,DhcpInfo获取android IP
  6. Android(安卓)获取状态栏的高度
  7. Android启动优化
  8. linux基础教程--安装Android(安卓)SDK
  9. android之View属性
  10. cocos2d-x3.0beta版+NDK-r9b在android上