今天介绍一下Android中怎么实现ImageView的缩放和移动,自定义TouchImageView。

 public class TouchImageView extends ImageView {

     Matrix matrix;

     // We can be in one of these 3 states
static final int NONE = ;
static final int DRAG = ;
static final int ZOOM = ;
int mode = NONE; // Remember some things for zooming
PointF last = new PointF();
PointF start = new PointF();
float minScale = 1f;
float maxScale = 3f;
float[] m; int viewWidth, viewHeight;
static final int CLICK = ;
float saveScale = 1f;
protected float origWidth, origHeight;
int oldMeasuredWidth, oldMeasuredHeight; ScaleGestureDetector mScaleDetector; Context context; public TouchImageView(Context context) {
super(context);
sharedConstructing(context);
} public TouchImageView(Context context, AttributeSet attrs) {
super(context, attrs);
sharedConstructing(context);
} private void sharedConstructing(Context context) {
super.setClickable(true);
this.context = context;
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
matrix = new Matrix();
m = new float[];
setImageMatrix(matrix);
setScaleType(ScaleType.MATRIX); setOnTouchListener(new OnTouchListener() { @Override
public boolean onTouch(View v, MotionEvent event) {
mScaleDetector.onTouchEvent(event);
PointF curr = new PointF(event.getX(), event.getY()); switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
last.set(curr);
start.set(last);
mode = DRAG;
break; case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
float deltaX = curr.x - last.x;
float deltaY = curr.y - last.y;
float fixTransX = getFixDragTrans(deltaX, viewWidth, origWidth * saveScale);
float fixTransY = getFixDragTrans(deltaY, viewHeight, origHeight * saveScale);
matrix.postTranslate(fixTransX, fixTransY);
fixTrans();
last.set(curr.x, curr.y);
}
break; case MotionEvent.ACTION_UP:
mode = NONE;
int xDiff = (int) Math.abs(curr.x - start.x);
int yDiff = (int) Math.abs(curr.y - start.y);
if (xDiff < CLICK && yDiff < CLICK)
performClick();
break; case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
} setImageMatrix(matrix);
invalidate();
return true; // indicate event was handled
} });
} public void setMaxZoom(float x) {
maxScale = x;
} private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
mode = ZOOM;
return true;
} @Override
public boolean onScale(ScaleGestureDetector detector) {
float mScaleFactor = detector.getScaleFactor();
float origScale = saveScale;
saveScale *= mScaleFactor;
if (saveScale > maxScale) {
saveScale = maxScale;
mScaleFactor = maxScale / origScale;
} else if (saveScale < minScale) {
saveScale = minScale;
mScaleFactor = minScale / origScale;
} if (origWidth * saveScale <= viewWidth || origHeight * saveScale <= viewHeight)
matrix.postScale(mScaleFactor, mScaleFactor, viewWidth / , viewHeight / );
else
matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY()); fixTrans();
return true;
}
} void fixTrans() {
matrix.getValues(m);
float transX = m[Matrix.MTRANS_X];
float transY = m[Matrix.MTRANS_Y]; float fixTransX = getFixTrans(transX, viewWidth, origWidth * saveScale);
float fixTransY = getFixTrans(transY, viewHeight, origHeight * saveScale); if (fixTransX != || fixTransY != )
matrix.postTranslate(fixTransX, fixTransY);
} float getFixTrans(float trans, float viewSize, float contentSize) {
float minTrans, maxTrans; if (contentSize <= viewSize) {
minTrans = ;
maxTrans = viewSize - contentSize;
} else {
minTrans = viewSize - contentSize;
maxTrans = ;
} if (trans < minTrans)
return -trans + minTrans;
if (trans > maxTrans)
return -trans + maxTrans;
return ;
} float getFixDragTrans(float delta, float viewSize, float contentSize) {
if (contentSize <= viewSize) {
return ;
}
return delta;
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
viewWidth = MeasureSpec.getSize(widthMeasureSpec);
viewHeight = MeasureSpec.getSize(heightMeasureSpec); //
// Rescales image on rotation
//
if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight
|| viewWidth == || viewHeight == )
return;
oldMeasuredHeight = viewHeight;
oldMeasuredWidth = viewWidth; if (saveScale == ) {
//Fit to screen.
float scale; Drawable drawable = getDrawable();
if (drawable == null || drawable.getIntrinsicWidth() == || drawable.getIntrinsicHeight() == )
return;
int bmWidth = drawable.getIntrinsicWidth();
int bmHeight = drawable.getIntrinsicHeight(); Log.d("bmSize", "bmWidth: " + bmWidth + " bmHeight : " + bmHeight); float scaleX = (float) viewWidth / (float) bmWidth;
float scaleY = (float) viewHeight / (float) bmHeight;
scale = Math.min(scaleX, scaleY);
matrix.setScale(scale, scale); // Center the image
float redundantYSpace = (float) viewHeight - (scale * (float) bmHeight);
float redundantXSpace = (float) viewWidth - (scale * (float) bmWidth);
redundantYSpace /= (float) ;
redundantXSpace /= (float) ; matrix.postTranslate(redundantXSpace, redundantYSpace); origWidth = viewWidth - * redundantXSpace;
origHeight = viewHeight - * redundantYSpace;
setImageMatrix(matrix);
}
fixTrans();
}
}

Android 移动缩放的ImageView的更多相关文章

  1. android学习笔记之ImageView的scaleType属性

    我们知道,ImageView有一个属性叫做scaleType,它的取值一共有八种,分别是:matrix,fitXY,fitStart,fitCenter,fitEnd,center,centerCro ...

  2. Android开源项目发现---ImageView 篇(持续更新)

    1. PhotoView 支持双击或双指缩放的ImageView 在ViewPager等Scrolling view中正常使用,相比上面的AndroidTouchGallery,不仅支持ViewPag ...

  3. 一起学习android图像缩放资源 (27)

    效果图: 在平时载入图片时,我会使用SetImageBitmap.setImageResource.BitmapFactory.decodeResource来设置一张图 片通过以上方法来设置图片时.会 ...

  4. Android基础控件ImageView的使用

    1.相关属性 <!--src 设置内容--> <!--background 设置背景--> <!--alpha 设置透明度 --> <!--adjustVie ...

  5. Android控件之ImageView(显示图片的控件)

    一.ImageView属性: android:src = "@drawable/ic_launcher"——ImageView的内容图像(可以和android:background ...

  6. android ImageView的属性android:scaleType,即ImageView.setScaleType(ImageView.ScaleType)

    实例 <ImageView android:id="@+id/image" android:layout_width="fill_parent" andr ...

  7. ImageView的属性android:scaleType,即ImageView.setScaleType(ImageView.ScaleType)

    1 imageView.setScaleType(ImageView.ScaleType.FIT_XY ); 1 这里我们重点理解ImageView的属性android:scaleType,即Imag ...

  8. android中动态修改ImageView控件的宽高度

    本例实现了动态修改ImageView控件的宽高度,有两个按钮,一个按钮实现放大image,一个按钮实现缩小image activity_main.xml <?xml version=" ...

  9. android开发布局文件imageview 图片等比例缩放:

    ImageView的属性scaleType,如果等比缩放的话,就使用CenterInside,如果想固定大小的话,就CenterCrop <?xml version="1.0" ...

随机推荐

  1. Asp.NET设置Session过期时间的四种方式

    在Asp.net中,可以有四处设置Session的过期时间: 一.全局网站(即服务器)级 IIS-网站-属性-Asp.net-编辑配置-状态管理-会话超时(分钟)-设置为120,即为2小时,即120分 ...

  2. IIS_Mvc发布

    网站发布步骤: 这部分是转载文章 在此标明出处,以前有文章是转的没标明的请谅解,因为有些已经无法找到出处,或者与其它原因. 如有冒犯请联系本人,或删除,或标明出处. 因为好的文章,以前只想收藏,但连接 ...

  3. hdu_2089 不要62

    数位动态规划     数位动态规划是求解一个大区间[L, R]中间满足条件Q的所有数字的个数(或者和,或其他)的一种方法.它通过分析每一位上的数字,一般用 dp[len][digit][...] 来表 ...

  4. iOS开发 仿淘宝,京东商品详情3D动画

    - (void)show { [[UIApplication sharedApplication].windows[0] addSubview:self.projectView]; CGRect fr ...

  5. Hbase之进行批处理操作

    import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; impo ...

  6. SCCM 部署操作系统 ,提示权限问题,报错:0xc00000098

    SCCM 部署操作系统 ,提示权限问题,报错:0xc00000098 这个问题通过查看日志,论坛搜索,博客等.下面是最终的解决方法: 1.检查所有组件是否已安装.(IIS组件等).(分发站点证书是否正 ...

  7. Android Toolbar样式定制详解

    前言 Marterial Design出来也有一段时间了,为了紧跟Google的设计规范,决定在项目中使用Toolbar.使用了一段时间之后,发现很多时候原始的Toolbar并不能满足项目的要求.为了 ...

  8. a、b交换与比较

    1.有两个变量a,b,不用if.?: .switch 或其他判断语句,找出两个数中 较大的: int max = ((a+b)+abs(a-b))/2 较小的: int min = ((a+b)-ab ...

  9. 如何组织较大项目的MVC文件夹结构

    现在还用不到,拷贝下来备用,原文链接 2016 年 9 月 第 31 卷,第 9 期 ASP.NET Core - ASP.NET Core MVC 的功能切分 作者 Steve Smith | 20 ...

  10. left join与on,where 结合一起用的异同

    I.数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户. 在使用left join时,on和where条件的区别如下: 1. on条件是在生成临时表时使用 ...