在学习之前,不使用第三方框架的情况下,会有:哇,这咋搞,直接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.使用 手势处理类,处理滑动事件
//第一步 初始化成员变量 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(); }
@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 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); }
//将 时间传递 发给 收拾处理器 @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(); } } }
结合老婆生产之后,家庭成员之间关系的变化情况,我在想,如果以后我生了女儿,我会不会同意我的宝贝女儿找家里同胞兄弟个数大于一个的男朋友,我觉得我不会同意,绝对不会
本人家里有个哥哥,在这么一个上有老下有小的人生阶段,我心里苦水真的不知道向谁诉说,只能打碎牙齿往肚里咽吧,也许有一天我也会崩溃的坐在大首都的某个角落大哭一场,被人拍下上了抖音、快手吧,人生不易,爱父母,爱妻儿,好好学习且行且珍惜吧,谢谢你读完了这段话,
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算