长图大图加载
需求:在项目开发中需要长图显示以及大图、巨图显示。
1.长图加载
长图加载显示
由于长图大小比较大,占用的内存比较多,所以需要优化加载。
理论:我们只加载需要显示的大小,其他部分不加载。
1.1画出图形
创建一个自定义控件继承View,它需要的参数:
//需要显示的区域
private Rect mRect;
//由于需要复用,所有需要option
private BitmapFactory.Options mOption;
//长图需要通过手势滑动来操作
private GestureDetector mGestureDetector;
//滑动帮助类
private Scroller mScroller;
//图片的宽度
private int mImageWidth;
//图片的高度
private int mImageHeight;
//控件的宽度
private int mViewWidth;
//控件的高度
private int mViewHeight;
//图片缩放因子
private float mScale;
//区域解码器
private BitmapRegionDecoder mDecode;
//需要展示的图片,是被复用的
private Bitmap mBitmap;
构造函数中初始化需要显示的矩形区域、手势识别类、滑动帮助类等
public BigView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mRect = new Rect();
mOption = new BitmapFactory.Options();
mGestureDetector = new GestureDetector(context, this);
setOnTouchListener(this);
mScroller = new Scroller(context);
}
为使用者提供一个输入图片的方法,参数使用输入流,方便使用。
/**
* 由使用者输入一张图片
*
* @param is 图片输入流
*/
public void setImage(InputStream is) {
mOption.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, mOption);
mImageWidth = mOption.outWidth;
mImageHeight = mOption.outHeight;
//开启复用内存
mOption.inMutable = true;
//设置格式,减少内存
mOption.inPreferredConfig = Bitmap.Config.RGB_565;
mOption.inJustDecodeBounds = false;
//创建一个区域解码器
try {
mDecode = BitmapRegionDecoder.newInstance(is, false);
} catch (IOException e) {
e.printStackTrace();
}
//刷新
requestLayout();
}
在自定义控件测量方法中,得到需要展示区域的大小,保存在Rect中。
/**
* 在控件测量中把需要内存区域获取,保存在Rect中
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//获取测量的view的大小
mViewWidth = getMeasuredWidth();
mViewHeight = getMeasuredHeight();
mRect.top = 0;
mRect.left = 0;
mRect.right = mImageWidth;
mScale = mViewWidth / (float) mImageWidth;
mRect.bottom = (int) (mViewHeight / mScale);
}
在onDraw中画出需要展示的内容
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//如果没有解码器 说明还没有图片,不需要绘制
if (null == mDecode) {
return;
}
mOption.inBitmap = mBitmap;
//通过解码器把图解码出来,只加载矩形区域的内容
mBitmap = mDecode.decodeRegion(mRect, mOption);
//把得到的矩形局域大小的图片通过缩放因子,缩放成控件大小
Matrix matrix = new Matrix();
matrix.setScale(mScale, mScale);
canvas.drawBitmap(mBitmap, matrix, null);
}
1.2滑动图形
将控件的onTouch事件交给手势识别来处理。
@Override
public boolean onTouch(View v, MotionEvent event) {
//将onTouch事件交给手势处理
return mGestureDetector.onTouchEvent(event);
}
如果控件由于惯性正在滑动,需要用户在点击的时候,立刻停止滑动,需要使用滑动帮助类强制停止滑动。
/**
* 手指按下的回调
*/
@Override
public boolean onDown(MotionEvent e) {
//如果移动还没有停止,强制停止
if (!mScroller.isFinished()) {
mScroller.forceFinis

本文详细介绍了在Android中处理长图和大图的加载与显示,包括只加载可视区域以优化内存使用,实现手势滑动、惯性滑动以及长图加载的完整代码示例。此外,还提到了大图加载和缩放的实现思路。

444

被折叠的 条评论
为什么被折叠?



