项目中需要用到家在大图,图片长度大概40000像素,直接加载会抛异常,所以准备自己写一个大图的加载view,
需要实现的功能包括
1.加载出大图
2.可以滑动,需要处理边界
3.支持手势的缩放
1加载大图
这里主要使用了 BitmapRegionDecoder 这个类,初始化需要一个bitmap的inputStream, 可以根据添加的矩形区域,获取到当前bitmap在该区域的bitmap,然后绘制到view中,
而Bitmap的获取,需要注意要复用bitmap内存,每次都不需要获取新的内存空间,避免内存的分配与回收
需要注意的是:
api19以前格式只为jpg,png,同等宽高,inSampleSize为1才能复用
api19以后复用复用的bitmap的内存 必须大于等于需要申请的bitmap的内存
主要代码:
try {
mBitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, false);
} catch (IOException e) {
e.printStackTrace();
}
//这里mRect是需要截取的矩形区域,mBitmap是截取到的bitmap
mBitmap = mBitmapRegionDecoder.decodeRegion(mRect, mOptions);
canvas.drawBitmap(mBitmap, matrix, null);
滑动,普通手势处理边界;惯性手势;双击缩放
滑动主要是使用 GestureDetector ,
OnGestureListener,Scroller
//通过Scroller可以实现View在一定时间间隔内的弹性滑动
基本使用
//1.
mGesture = new GestureDetector(context,OnGestureListener);
@Override
public boolean onTouch(View v, MotionEvent event) {
// 2,直接将事件传递给手势事件处理
mGesture.onTouchEvent(event);
return true;
}
//OnGestureListener中
@Override
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
/**
*e1 就是开始事件,手指按下去,获取坐标
*e2 当前事件;
*/
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//3 拿到拖动事件,并修改矩形位置,重新绘制
// 上下移动的时候,mRect需要改变显示区域
mRect.offset((int)distanceX,(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);
}
if(mRect.right > mImageWidth){
mRect.right = mImageWidth;
mRect.left = mImageWidth-(int)(mViewWidth/mScale);
}
if(mRect.left < 0 ){
mRect.left = 0;
mRect.right = (int)(mViewWidth/mScale);
}
invalidate();
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
/**
* @param e1 在手抬起来的时候回调的
* @param e2
* @param velocityX x方向速度;
* @param velocityY y方向速度;
* @return
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//将惯性事件交给mScroller
mScroller.fling(mRect.left, mRect.top,
(int) -velocityX, (int) -velocityY,
0, viewWidth,
0, viewHeight
);
return false;
}
// 处理结果 view的方法;
@Override
public void computeScroll() {
if(mScroller.isFinished()){
return;
}
if(mScroller.computeScrollOffset()){
mRect.top = mScroller.getCurrY();
mRect.bottom = mRect.top+(int)(mViewHeight/mScale);
invalidate();
}
}
手势可以添加双击手势
OnDoubleTapListener,(双击手势)
mGestureDetector.setOnDoubleTapListener(this);
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return false;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
// 双击事件
if(mScale < originalScale*1.5){
mScale = originalScale*3;
}else{
mScale = originalScale;
}
mRect.right = mRect.left+(int)(mViewWidth/mScale);
mRect.bottom = mRect.top+(int)(mViewHeight/mScale);
// 移动时,处理到达顶部和底部的情况
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);
}
if(mRect.right > mImageWidth){
mRect.right = mImageWidth;
mRect.left = mImageWidth-(int)(mViewWidth/mScale);
}
if(mRect.left < 0 ){
mRect.left = 0;
mRect.right = (int)(mViewWidth/mScale);
}
invalidate();
return true;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return false;
}
3.缩放手势
mScaleGestureDetector = new ScaleGestureDetector(context,new ScaleGesture());
// 5:处理点击事件
@Override
public boolean onTouch(View v, MotionEvent event) {
// 直接将时间传递给手势事件处理
mScaleGestureDetector.onTouchEvent(event);
return true;
}
// 处理缩放的回调事件
class ScaleGesture extends ScaleGestureDetector.SimpleOnScaleGestureListener{
@Override
public boolean onScale(ScaleGestureDetector detector) {
float scale = mScale;
scale += detector.getScaleFactor() -1;
if(scale <= originalScale){
scale = originalScale;
}else if(scale > originalScale*5){
scale = originalScale*5;
}
mRect.right = mRect.left + (int)(mViewWidth/scale);
mRect.bottom = mRect.top + (int)(mViewHeight/scale);
mScale = scale;
invalidate();
return true;
}
}
网友评论