




已阅读5页,还剩22页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
最近做一个相册浏览器,类似于Android系统自带的那种,可以实现缩放。找了很多帖子,没有想要的那种结果,要么只能拖动,要么只能缩放,要综合两种效果的却没有。经过自己的钻研,重写了ImageViewTouchBase,并实现自己的类来继承Gallery,在该类里边实现缩放事件,然后在xml文件里边加载这个类。终于出来了自己想要的结果,下面与大家分享一下。先看几张截图:图一:原图 图二:两张图片切换的动画 图三:通过手指实现图片放大 布局文件代码: 两个主要的java类:Gallery代码package com.lyc.pic;import android.content.Context;import android.graphics.Matrix;import android.graphics.Rect;import android.util.AttributeSet;import android.util.Log;import android.view.GestureDetector;import android.view.KeyEvent;import android.view.MotionEvent;import android.view.View;import android.view.GestureDetector.SimpleOnGestureListener;import android.widget.Gallery;public class MyGallery extends Gallery private GestureDetector gestureScanner; private MyImageView imageView;public MyGallery(Context context) super(context);public MyGallery(Context context, AttributeSet attrs, int defStyle) super(context, attrs, defStyle);public MyGallery(Context context, AttributeSet attrs) super(context, attrs);gestureScanner = new GestureDetector(new MySimpleGesture();this.setOnTouchListener(new OnTouchListener() float baseValue;float originalScale;/重写onTouch方法实现缩放Overridepublic boolean onTouch(View v, MotionEvent event) View view = MyGallery.this.getSelectedView();if (view instanceof MyImageView) imageView = (MyImageView) view;if (event.getAction() = MotionEvent.ACTION_DOWN) baseValue = 0;originalScale = imageView.getScale();if (event.getAction() = MotionEvent.ACTION_MOVE) /处理拖动if (event.getPointerCount() = 2) float x = event.getX(0) - event.getX(1);float y = event.getY(0) - event.getY(1);float value = (float) Math.sqrt(x * x + y * y);/ 计算两点的距离/ System.out.println(value: + value);if (baseValue = 0) baseValue = value; else float scale = value / baseValue;/ 当前两点间的距离除以手指落下时两点间的距离就是需要缩放的比例。/ scale the imageimageView.zoomTo(originalScale * scale, x + event.getX(1), y + event.getY(1);return false;);Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) View view = MyGallery.this.getSelectedView();if (view instanceof MyImageView) imageView = (MyImageView) view;float v = new float9;Matrix m = imageView.getImageMatrix();m.getValues(v);/ 图片实时的上下左右坐标float left, right;/ 图片的实时宽,高float width, height;width = imageView.getScale() * imageView.getImageWidth();height = imageView.getScale() * imageView.getImageHeight();/ 下面逻辑为移动图片和滑动gallery换屏的逻辑。如果没对整个框架了解的非常清晰,勿动以下代码if (int) width = MianActivity.screenWidth & (int) height = MianActivity.screenHeight)/ 如果图片当前大小 0)/ 向左滑动if (r.left 0) / 判断当前ImageView是否显示完全super.onScroll(e1, e2, distanceX, distanceY); else if (right MianActivity.screenWidth) Log.i(screenWidth, MianActivity.screenWidth1: + MianActivity.screenWidth);super.onScroll(e1, e2, distanceX, distanceY); else imageView.postTranslate(-distanceX, -distanceY); else if (distanceX 0)/ 向右滑动if (r.right 0) super.onScroll(e1, e2, distanceX, distanceY); else imageView.postTranslate(-distanceX, -distanceY);/ if (distanceX 0)/ 向左滑动/ / if (r.left 0) / 判断当前ImageView是否显示完全/ super.onScroll(e1, e2, distanceX, distanceY);/ else if (right = MianActivity.screenWidth) / super.onScroll(e1, e2, distanceX, distanceY);/ else / imageView.postTranslate(-distanceX, -distanceY);/ / else if (distanceX e1.getX();Overridepublic boolean onTouchEvent(MotionEvent event) gestureScanner.onTouchEvent(event);switch (event.getAction() case MotionEvent.ACTION_UP:/ 判断上下边界是否越界View view = MyGallery.this.getSelectedView();if (view instanceof MyImageView) imageView = (MyImageView) view;float width = imageView.getScale() * imageView.getImageWidth();float height = imageView.getScale() * imageView.getImageHeight();if (int) width = MianActivity.screenWidth & (int) height = MianActivity.screenHeight)/ 如果图片当前大小 0) imageView.postTranslateDur(-top, 200f);Log.i(lyc, bottom: + bottom);if (bottom imageView.getScaleRate() imageView.zoomTo(imageView.getScaleRate(), MianActivity.screenWidth / 2, MianActivity.screenHeight / 2, 200f);/ imageView.layoutToCenter(); else imageView.zoomTo(1.0f, MianActivity.screenWidth / 2, MianActivity.screenHeight / 2, 200f); else / return super.onDoubleTap(e);return true;根据android系统自带的ImageViewTouchBase代码修改的代码:package com.lyc.pic;import java.io.InputStream;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.RectF;import android.os.Handler;import android.util.AttributeSet;import android.util.Log;import android.view.KeyEvent;import android.widget.ImageView;public class MyImageView extends ImageView SuppressWarnings(unused)private static final String TAG = ImageViewTouchBase;protected Matrix mBaseMatrix = new Matrix();protected Matrix mSuppMatrix = new Matrix();private final Matrix mDisplayMatrix = new Matrix();private final float mMatrixValues = new float9;/ The current bitmap being displayed./ protected final RotateBitmap mBitmapDisplayed = new RotateBitmap(null);protected Bitmap image = null;int mThisWidth = -1, mThisHeight = -1;float mMaxZoom = 2.0f;/ 最大缩放比例float mMinZoom ;/ 最小缩放比例private int imageWidth;/ 图片的原始宽度private int imageHeight;/ 图片的原始高度private float scaleRate;/ 图片适应屏幕的缩放比例protected void onDraw(Canvas canvas) /正在显示的图片实际宽高float width = imageWidth*getScale();float height = imageHeight*getScale();if (width MianActivity.screenWidth) / 如果图宽大于屏宽,就不用水平居中center(false, true); else center(true, true);super.onDraw(canvas);public MyImageView(Context context, int imageWidth, int imageHeight) super(context);this.imageHeight = imageHeight;this.imageWidth = imageWidth;init();public MyImageView(Context context, AttributeSet attrs, int imageWidth, int imageHeight) super(context, attrs);this.imageHeight = imageHeight;this.imageWidth = imageWidth;init();private void arithScaleRate() float scaleWidth = MianActivity.screenWidth / (float) imageWidth;float scaleHeight = MianActivity.screenHeight / (float) imageHeight;scaleRate = Math.min(scaleWidth, scaleHeight);public float getScaleRate() return scaleRate;public int getImageWidth() return imageWidth;public void setImageWidth(int imageWidth) this.imageWidth = imageWidth;public int getImageHeight() return imageHeight;public void setImageHeight(int imageHeight) this.imageHeight = imageHeight;Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) if (keyCode = KeyEvent.KEYCODE_BACK & event.getRepeatCount() = 0) event.startTracking();return true;return super.onKeyDown(keyCode, event);Overridepublic boolean onKeyUp(int keyCode, KeyEvent event) if (keyCode = KeyEvent.KEYCODE_BACK & event.isTracking() & !event.isCanceled() if (getScale() 1.0f) / If were zoomed in, pressing Back jumps out to show the/ entire image, otherwise Back returns the user to the gallery.zoomTo(1.0f);return true;return super.onKeyUp(keyCode, event);protected Handler mHandler = new Handler();Overridepublic void setImageBitmap(Bitmap bitmap) super.setImageBitmap(bitmap);image = bitmap;/ 计算适应屏幕的比例arithScaleRate();/缩放到屏幕大小zoomTo(scaleRate,MianActivity.screenWidth / 2f, MianActivity.screenHeight / 2f);/居中layoutToCenter();protected void center(boolean horizontal, boolean vertical) if (image = null) return;Matrix m = getImageViewMatrix();RectF rect = new RectF(0, 0, image.getWidth(), image.getHeight();m.mapRect(rect);float height = rect.height();float width = rect.width();float deltaX = 0, deltaY = 0;if (vertical) int viewHeight = getHeight();if (height 0) deltaY = -rect.top; else if (rect.bottom viewHeight) deltaY = getHeight() - rect.bottom;if (horizontal) int viewWidth = getWidth();if (width 0) deltaX = -rect.left; else if (rect.right 0)tran_width = fill_width/2;if(fill_height0)tran_height = fill_height/2;postTranslate(tran_width, tran_height);setImageMatrix(getImageViewMatrix();protected float getValue(Matrix matrix, int whichValue) matrix.getValues(mMatrixValues);mMinZoom =( MianActivity.screenWidth/2f)/imageWidth;return mMatrixValueswhichValue;/ Get the scale factor out of the tected float getScale(Matrix matrix) return getValue(matrix, Matrix.MSCALE_X);protected float getScale() return getScale(mSuppMatrix);/ Combine the base matrix and the supp matrix to make the final tected Matrix getImageViewMatrix() / The final matrix is computed as the concatentation of the base matrix/ and the supplementary matrix.mDisplayMatrix.set(mBaseMatrix);mDisplayMatrix.postConcat(mSuppMatrix);return mDisplayMatrix;static final float SCALE_RATE = 1.25F;/ Sets the maximum zoom, which is a scale relative to the base matrix. It/ is calculated to show the image at 400% zoom regardless of screen or/ image orientation. If in the future we decode the full 3 megapixel image,/ rather than the current 1024x768, this should be changed down to 200%.protected float maxZoom() if (image = null) return 1F;float fw = (float) image.getWidth() / (float) mThisWidth;float fh = (float) image.getHeight() / (float) mThisHeight;float max = Math.max(fw, fh) * 4;return max;protected void zoomTo(float scale, float centerX, float centerY) if (scale mMaxZoom) scale = mMaxZoom; else if (scale mMinZoom) scale = mMinZoom;float oldScale = getScale();float deltaScale = scale / oldScale;mSuppMatrix.postScale(deltaScale, deltaScale, centerX, centerY);setImageMatrix(getImageViewMatrix();center(true, true);protected void zoomTo(final float scale, final float centerX, final float centerY, final float durationMs) final float incrementPerMs = (scale - getScale() / durationMs;final float oldScale = getScale();final long startTime = System.currentTimeMillis();mHandler.post(new Runnable() public void run() long now = System.currentTimeMillis();float currentMs = Math.min(durationMs, now - startTime);float target = oldScale + (incrementPerMs * currentMs);zoomTo(target, centerX, centerY);if (currentMs = mMaxZoom) return; / Dont let the user zoom into the molecular level. else if (getScale() = mMinZoom) return;if (image = null) return;float cx = getWidth() / 2F;float cy = getHeight() / 2F;mSuppMatrix.postScale(rate, rate, cx, c
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025保健品区域独家销售代理合同范本
- 2025版双方新能源汽车研发生产合同协议
- 2025版片石石材开采与运输一体化合同协议书范本
- 2025版商业承兑汇票居间服务与乡村振兴战略合作合同
- 2025年度新能源发电项目电力改造合同范本
- 2025版体育产业新员工保密及赛事信息保护合同范例
- 2025办公场所租赁合同:全包式办公场所租赁管理合同
- 2025年售楼部环境绿化养护合同
- 2025大客户在线教育平台合作合同
- 2025年度道路施工围挡定制安装服务协议
- 烟草香味化学
- 院感培训试题及
- 电气照明系统课件
- 临时用水施工专项方案
- 北京市各县区乡镇行政村村庄村名明细
- GB∕T 9286-2021 色漆和清漆 划格试验
- DB35∕T 1844-2019 高速公路边坡工程监测技术规程
- 720全景照片制作方案及发布流程
- 工作责任心主题培训ppt课件(PPT 26页)
- 除尘器基础知识培训资料(54页)ppt课件
- 完整解读新版《英语》新课标2022年《义务教育英语课程标准(2022年版)》PPT课件
评论
0/150
提交评论