Android 加载超大长图及原理

我们在开发中偶尔会遇到加载超大长图,类似于微信n多页聊天记录截图加载。但这类图片一般都会很大,几兆、十几兆、甚至几十兆,很容易造成内存溢出,今天笔者给大家提供一个可以满足此类需求的简单的自定义view。具体原理就是图片缩放,只加载屏幕显示区域图片,内存复用。代码很简单,注视也很相信,可以拿来直接用。

public class BigView extends View implements GestureDetector.OnGestureListener,View.OnTouchListener {private  Scroller mScroll;//手势private  GestureDetector mGestureDetector;private BitmapFactory.Options mOptions;private int mImageHeight;private int mImageWidht;//手机屏幕宽高private int mViewHeight;private int mViewWidth;//图片缩放因子private float mScale;private Rect mRect;private Bitmap mBitmap;//bitmap解码器private BitmapRegionDecoder mDecoder;public BigView(Context context) {this(context,null);}public BigView(Context context, AttributeSet attrs) {this(context, attrs,0);}public BigView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mOptions=new  BitmapFactory.Options();//内存复用mGestureDetector=new GestureDetector(context,this);mScroll =new Scroller(context);mRect=new Rect();setOnTouchListener(this);}public void setImage(InputStream inputStream){//只将大图的边框加载到内存mOptions.inJustDecodeBounds=true;//将图片边宽加载到optionsBitmapFactory.decodeStream(inputStream,null,mOptions);mImageHeight=mOptions.outHeight;mImageWidht=mOptions.outWidth;//设置内存可复用mOptions.inMutable=true;//设置图片编码格式mOptions.inPreferredConfig=Bitmap.Config.RGB_565;mOptions.inJustDecodeBounds=false;try {//解码图片mDecoder= BitmapRegionDecoder.newInstance(inputStream,false);} catch (IOException e) {e.printStackTrace();}//requestLayout方法会导致View的onMeasure、onLayout、onDraw方法被调用;requestLayout();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mViewHeight=getMeasuredHeight();mViewWidth=getMeasuredWidth();mScale=mViewWidth/(float)mImageWidht;//等比例缩放后图片所占区域mRect.top=0;mRect.left=0;mRect.right= mImageWidht;mRect.bottom= (int) (mViewHeight/mScale);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if(mDecoder==null)return;//内存复用,分配空间mOptions.inBitmap=mBitmap;//指定解码区域mBitmap=mDecoder.decodeRegion(mRect,mOptions);Matrix matrix=new Matrix();//将图片缩放到手机屏幕内matrix.preScale(mScale,mScale);canvas.drawBitmap(mBitmap,matrix,null);}@Overridepublic boolean onTouch(View view, MotionEvent motionEvent) {//将触摸时间分发给手势return mGestureDetector.onTouchEvent(motionEvent);}@Overridepublic boolean onDown(MotionEvent motionEvent) {//当按下屏幕时,如果正在滑动,则强制停止滑动if(!mScroll.isFinished()){mScroll.forceFinished(true);}return true;}@Overridepublic boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {//滑动时rect偏移量计算mRect.offset(0, (int) v1);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);}//调用ondraw方法invalidate();return false;}@Overridepublic boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {mScroll.fling(0,mRect.top,0,(int)-v1,0,0,0,mImageHeight-(int)(mViewHeight/mScale));return false;}//处理滚动结果@Overridepublic void computeScroll() {if(mScroll.isFinished())return;if(mScroll.computeScrollOffset()){mRect.top=mScroll.getCurrY();mRect.bottom=mScroll.getCurrY()+(int)(mViewHeight/mScale);//调用ondraw方法invalidate();}super.computeScroll();}@Overridepublic void onShowPress(MotionEvent motionEvent) {}@Overridepublic boolean onSingleTapUp(MotionEvent motionEvent) {return false;}@Overridepublic void onLongPress(MotionEvent motionEvent) {}}

外部只需要简单调用即可使用 bigView.setImage(inputStream);

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);BigView bigView=findViewById(R.id.bigView);InputStream inputStream= null;try {inputStream = getAssets().open("big.jpeg");bigView.setImage(inputStream);} catch (IOException e) {e.printStackTrace();}}
}

Android 加载超大长图及原理相关推荐

  1. android 加载大长图,android加载长图片的方法

    1.很多应用都有加载一张长图片,用户可以上下拉动图片. 自己没有好的想法,那只好百度咯.结果都说用webview来实现,好吧那就只好先试一下了. 2.自己写了简单的html,然后webview加载.图 ...

  2. android 加载类似长微博的超长图或超大图subsampling-scale-image-view

    超长图直接加载的时候有可能会出现超出Bitmap最大高度,直接使用BitmapFactory.Options来缩放图片可能会把图片缩的太小,所以加载长图最好还是用BitmapRegionDecoder ...

  3. android 加载外部矢量图SVG

    转自:http://blog.csdn.net/jiabailong/article/details/53736689 android加载矢量图的方式主要有以下两种: 一.Web方式 利用WebVIe ...

  4. android 展示大图,Android 加载超大图(原图)分析

    众所周知,Android的ImageView不支持加载大图(高分辨率),会直接报错,如果不是特别大的图片,也可以选择使用WebView来加载,并且直接可以实现手势方法缩小平移等效果,但是如果图片特别长 ...

  5. Android 图片预览器加载微博长图,大图

    通常图片预览的做法是ViewPager+PhotoView,但是遇到很长的图(比如微博长图),在设置 android:scaleType="centerCrop" 这个属性的前提下 ...

  6. Glide加载大图长图

    这里用的Glide是4.11.0的 第一种方法: Glide.with(activity).load(yourUrl).asBitmap().into(new SimpleTarget<Bitm ...

  7. android 漫画加载方案,Android加载长图的多种方案分享

    背景介绍 在某些特定场景下,我们需要考虑加载长图的需求,比如加载一幅<清明上河图>,这个好像有点过分了,那就加载1/2的<清明上河图>吧... 那TMD还不是一样道理. 言归正 ...

  8. Android加载/处理超大图片神器!SubsamplingScaleImageView(subsampling-scale-image-view)【系列1】...

     Android加载/处理超大图片神器!SubsamplingScaleImageView(subsampling-scale-image-view)[系列1] Android在加载或者处理超大巨 ...

  9. Android加载/处理超大图片神器!SubsamplingScaleImageView(subsampling-scale-image-view)【系列1】

     Android加载/处理超大图片神器!SubsamplingScaleImageView(subsampling-scale-image-view)[系列1] Android在加载或者处理超大巨 ...

最新文章

  1. BeautifulSoup_第二节
  2. python3.7.2下载-Python编程神器 v3.7.2 最新免费版
  3. iis php 图片无法显示,iis php 图片无法显示怎么办
  4. 动态的添加和丢弃关键点---32
  5. C# TreeNode的使用方法
  6. java获取当前电脑的ip_使用Java获取当前计算机的IP地址
  7. Python+OpenCV:图像Harris角点检测(Harris Corner Detection)
  8. 两边双虚线是什么意思_锯齿车道、倒三角标志什么意思?以下5种交通标线你认识几个?...
  9. 扎堆出海的抖音、今日头条、UC 头条们后来怎么样了?
  10. Storm并发度详解(转载)
  11. 金山卫士界面源码解读及界面库分离(4)
  12. 组合数学6--母函数与递推关系
  13. python(输入)正常返回否则出错重新
  14. Matlab GUI编程技巧(八):uitoolbar在图窗中创建工具栏
  15. 利用计算机模拟人类的活动属于,赠书 | 计算机能模拟人类心智吗?
  16. C++助教篇3_Week2不完全知识点
  17. python调用大漠插件寻路_python怎么调用大漠?
  18. vue项目获取下拉框选中id_vue获取下拉框值
  19. UE4 如何旋转模型骨骼
  20. ZOJ3587 Marlon's String

热门文章

  1. 用HashSet/Random写摇号器(数字不重复、无序)
  2. Mendix之REST服务详解
  3. 【Unity特效】LWRP/URP(Lightweight RP/Universal RP)和ShaderGraph下载及安装配置
  4. mysql中拼音排序的方法_mysql的中文数据按拼音排序的2个方法
  5. 微创业计划PPT模板
  6. 正则表达式基本字符含义
  7. python+pytest接口自动化(1)-接口测试基础
  8. 第二课作业(刘萌150206318)
  9. 机器学习基础01-线性代数
  10. vue+ts中引入组件自动提示 declare module