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);//设置onTouchListenersetOnTouchListener(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*/@Overrideprotected 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*/@Overrideprotected void onDraw(Canvas canvas){super.onDraw(canvas);//如果解码器拿不到,表示没有设置过要显示的图片if (null == mDecoder){return;}//复用上一张bitmaomOptions.inBitmap = bitmap;//解码指定区域bitmap = mDecoder.decodeRegion(mRect,mOptions);//把得到的矩阵大小的内存进行缩放Matrix matrix = new Matrix();matrix.setScale(mScale,mScale);//画出来canvas.drawBitmap(bitmap,matrix,null);}/*** 手按下的回调* @param e* @return*/@Overridepublic boolean onDown(MotionEvent e) {//如果移动还没有停止,强制停止if (!mScroller.isFinished()){mScroller.forceFinished(true);}//继续接受后续事件return true;}/**** @param e1 手势按下去的事件   开始获取坐标* @param e2 当前手势事件   获取当前坐标* @param distanceX  x方向移动的距离* @param distanceY  y方向移动的距离* @return*/@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {//上下移动的时候,需要改变显示的区域  改mRectmRect.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*/@Overridepublic 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;}/*** 使用上一个接口的计算结果*/@Overridepublic void computeScroll() {if (mScroller.isFinished()){return;}//true 表示当前滑动还没有结束if (mScroller.computeScrollOffset()){mRect.top = mScroller.getCurrY();mRect.bottom = mRect.top+(int)(mViewHeight/mScale);invalidate();}}@Overridepublic void onShowPress(MotionEvent e) {}@Overridepublic boolean onSingleTapUp(MotionEvent e) {return false;}@Overridepublic void onLongPress(MotionEvent e) {}@Overridepublic boolean onTouch(View v, MotionEvent event) {//交给手势处理return mGresureDetector.onTouchEvent(event);}
}

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

下面在activity中展示:

public class BigViewActivity extends AppCompatActivity {@Overrideprotected 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();}}}}
}

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

Android加载长图滑动显示相关推荐

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

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

  2. Android加载长图,仿微博长图滚动查看

    /** * Created by sunrui on 2017/3/8. * 加载长图片 * 解决步骤 * 1.将图片缩放到与控件等宽 * 2.判断缩放后的图片高度,如果高度大于控件高度较多(这里设置 ...

  3. android加载长图宽度自适应,Android使用Glide加载超长图

    app项目开发过程中,大都有查看图片详情的功能模块.实现的方式一般都是通过viewpager+photoView+Glide的方式.这种方式下,如果碰到加载超长图,比如说高清版的清明上河图/世界地图, ...

  4. Android之SubsamplingScaleImageView加载长图不能放缩问题

    1 问题 第三方开源框架用了这个第三方开源框架(SubsamplingScaleImageView)加载长图,但是源代码在有些手机上面不能进行放缩. private void displayLongP ...

  5. android如何加载长图

    思路:那就是对于一张巨型图片我们可否每次指定一块区域加载显示,然后通过改变这个区域完成整张巨图的加载呢?这样内存中只有完整图片的一块区域. 区域加载 1.BitmapRegionDecoder 指定B ...

  6. Android加载超长图(微博长图)

    对于一些需要加载超长图需求的同学,可能一开始使用使用bitmap或者inputstream转bitmap(或类似加载库)会发现出现图片太大加载不出来的问题(其实我也是遇到了这个问题ヽ(≧Д≦)ノ).解 ...

  7. android开发 加载大图,Android加载超长图(微博长图)

    对于一些需要加载超长图需求的同学,可能一开始使用使用bitmap或者inputstream转bitmap(或类似加载库)会发现出现图片太大加载不出来的问题(其实我也是遇到了这个问题ヽ(≧Д≦)ノ).解 ...

  8. android加载长图片出现Bitmap too large to be uploaded into a texture的解决方案

    最近做图片预览,加载长图片的时候,出现黑屏,无法加载图片的情况,查看Log,发现报出了Bitmap too large to be uploaded into a texture的错误.(我用的是Im ...

  9. Android 加载gif图,Glide

    个人中心 DownLoad Android 可以使用 Glide.Picasso.Fresco 等第三方库来加载 gif 图. 以 Glide 为例,可以按照以下步骤加载 gif 图: 1. 在 bu ...

最新文章

  1. 【星球知识卡片】人脸属性编辑都有哪些核心知识点,如何长期进行学习
  2. ABAP表抛FTP通用程序
  3. MQTT连接阿里云IoT(四)
  4. c语言多线编程程序,C语言之多线编程 来看看?
  5. 阿里面试官的分享Java面试中需要准备哪些多线程并发的技术要点
  6. 一文详解python的类方法,普通方法和静态方法
  7. 西门子 PLC 和 AB罗克韦尔 PLC 有什么区别?
  8. GraphPad Prism 9 for Mac 的使用教程
  9. Jsp中getParameter、getParameterValues、getParameterNames和getParameterMap用法详解
  10. “狗屁不通”文章生成器网页版代码
  11. 众包专访:开源众包让我安心——开源中国众包使用记录
  12. 股票学习-量柱和k线-第六天
  13. 登录失败 12306服务器不稳定,12306显示登陆失败43003怎么办-12306登录显示43003含义详解...
  14. 基于HSI颜色模型实现去除照片的“红眼现象”
  15. STM32F103C8T6平衡车
  16. 初学SpringMVC注册前端控制器DispatcherServlet:org.springframework.web.servlet.DispatcherServlet报红
  17. 企业微信和个人微信区别到底有哪些
  18. intern string java_Java-String.intern的深入研究
  19. 液晶显示模块(LCM)介绍
  20. 做需求分析师的几点困惑

热门文章

  1. Bootstrap实现遮罩层
  2. 设计模式(一)----设计模式概述及UML图解析
  3. 【数学建模】线性代数模型(上)
  4. EI数据库下载的记录主要格式说明
  5. 好家伙,阿里P8撰写的Java微服务架构全栈笔记GitHub一夜飞到榜首
  6. 收藏!100页自动化立体仓库PPT
  7. 微信小程序 刮刮卡效果
  8. 当物联网技术进入了玩具世界……
  9. JAVA程序设计:IPO(LeetCode:502)
  10. Python简单的音乐播放器1