今天刚发了一篇关于ImageView的缩放和拖拽的博客,然后我想了下,将他自定义下,方便我们来复用这个imageView,效果我就不多说了,http://blog.csdn.net/xiaanming/article/details/8827257就是这个效果,我只是把他抽出来自定义了下,代码还是贴上吧,我也将demo上传一下,有疑问大家指出来,大家共同学习,共同进步,呵呵

  1. package com.example.myimageview;
  2. import android.content.Context;
  3. import android.graphics.Bitmap;
  4. import android.graphics.Matrix;
  5. import android.graphics.PointF;
  6. import android.graphics.RectF;
  7. import android.graphics.drawable.BitmapDrawable;
  8. import android.util.AttributeSet;
  9. import android.util.DisplayMetrics;
  10. import android.util.FloatMath;
  11. import android.view.MotionEvent;
  12. import android.view.View;
  13. import android.widget.ImageView;
  14. public class MyImageView extends ImageView{
  15. Matrix matrix = new Matrix();
  16. Matrix savedMatrix = new Matrix();
  17. /**位图对象*/
  18. private Bitmap bitmap = null;
  19. /** 屏幕的分辨率*/
  20. private DisplayMetrics dm;
  21. /** 最小缩放比例*/
  22. float minScaleR = 1.0f;
  23. /** 最大缩放比例*/
  24. static final float MAX_SCALE = 15f;
  25. /** 初始状态*/
  26. static final int NONE = 0;
  27. /** 拖动*/
  28. static final int DRAG = 1;
  29. /** 缩放*/
  30. static final int ZOOM = 2;
  31. /** 当前模式*/
  32. int mode = NONE;
  33. /** 存储float类型的x,y值,就是你点下的坐标的X和Y*/
  34. PointF prev = new PointF();
  35. PointF mid = new PointF();
  36. float dist = 1f;
  37. public MyImageView(Context context) {
  38. super(context);
  39. setupView();
  40. }
  41. public MyImageView(Context context, AttributeSet attrs) {
  42. super(context, attrs);
  43. setupView();
  44. }
  45. public void setupView(){
  46. Context context = getContext();
  47. //获取屏幕分辨率,需要根据分辨率来使用图片居中
  48. dm = context.getResources().getDisplayMetrics();
  49. //根据MyImageView来获取bitmap对象
  50. BitmapDrawable bd = (BitmapDrawable)this.getDrawable();
  51. if(bd != null){
  52. bitmap = bd.getBitmap();
  53. }
  54. //设置ScaleType为ScaleType.MATRIX,这一步很重要
  55. this.setScaleType(ScaleType.MATRIX);
  56. this.setImageBitmap(bitmap);
  57. //bitmap为空就不调用center函数
  58. if(bitmap != null){
  59. center(true, true);
  60. }
  61. this.setImageMatrix(matrix);
  62. this.setOnTouchListener(new OnTouchListener() {
  63. @Override
  64. public boolean onTouch(View v, MotionEvent event) {
  65. switch (event.getAction() & MotionEvent.ACTION_MASK) {
  66. // 主点按下
  67. case MotionEvent.ACTION_DOWN:
  68. savedMatrix.set(matrix);
  69. prev.set(event.getX(), event.getY());
  70. mode = DRAG;
  71. break;
  72. // 副点按下
  73. case MotionEvent.ACTION_POINTER_DOWN:
  74. dist = spacing(event);
  75. // 如果连续两点距离大于10,则判定为多点模式
  76. if (spacing(event) > 10f) {
  77. savedMatrix.set(matrix);
  78. midPoint(mid, event);
  79. mode = ZOOM;
  80. }
  81. break;
  82. case MotionEvent.ACTION_UP:{
  83. break;
  84. }
  85. case MotionEvent.ACTION_POINTER_UP:
  86. mode = NONE;
  87. //savedMatrix.set(matrix);
  88. break;
  89. case MotionEvent.ACTION_MOVE:
  90. if (mode == DRAG) {
  91. matrix.set(savedMatrix);
  92. matrix.postTranslate(event.getX() - prev.x, event.getY()
  93. - prev.y);
  94. } else if (mode == ZOOM) {
  95. float newDist = spacing(event);
  96. if (newDist > 10f) {
  97. matrix.set(savedMatrix);
  98. float tScale = newDist / dist;
  99. matrix.postScale(tScale, tScale, mid.x, mid.y);
  100. }
  101. }
  102. break;
  103. }
  104. MyImageView.this.setImageMatrix(matrix);
  105. CheckView();
  106. return true;
  107. }
  108. });
  109. }
  110. /**
  111. * 横向、纵向居中
  112. */
  113. protected void center(boolean horizontal, boolean vertical) {
  114. Matrix m = new Matrix();
  115. m.set(matrix);
  116. RectF rect = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());
  117. m.mapRect(rect);
  118. float height = rect.height();
  119. float width = rect.width();
  120. float deltaX = 0, deltaY = 0;
  121. if (vertical) {
  122. // 图片小于屏幕大小,则居中显示。大于屏幕,上方留空则往上移,下方留空则往下移
  123. int screenHeight = dm.heightPixels;
  124. if (height < screenHeight) {
  125. deltaY = (screenHeight - height) / 2 - rect.top;
  126. } else if (rect.top > 0) {
  127. deltaY = -rect.top;
  128. } else if (rect.bottom < screenHeight) {
  129. deltaY = this.getHeight() - rect.bottom;
  130. }
  131. }
  132. if (horizontal) {
  133. int screenWidth = dm.widthPixels;
  134. if (width < screenWidth) {
  135. deltaX = (screenWidth - width) / 2 - rect.left;
  136. } else if (rect.left > 0) {
  137. deltaX = -rect.left;
  138. } else if (rect.right < screenWidth) {
  139. deltaX = screenWidth - rect.right;
  140. }
  141. }
  142. matrix.postTranslate(deltaX, deltaY);
  143. }
  144. /**
  145. * 限制最大最小缩放比例,自动居中
  146. */
  147. private void CheckView() {
  148. float p[] = new float[9];
  149. matrix.getValues(p);
  150. if (mode == ZOOM) {
  151. if (p[0] < minScaleR) {
  152. //Log.d("", "当前缩放级别:"+p[0]+",最小缩放级别:"+minScaleR);
  153. matrix.setScale(minScaleR, minScaleR);
  154. }
  155. if (p[0] > MAX_SCALE) {
  156. //Log.d("", "当前缩放级别:"+p[0]+",最大缩放级别:"+MAX_SCALE);
  157. matrix.set(savedMatrix);
  158. }
  159. }
  160. center(true, true);
  161. }
  162. /**
  163. * 两点的距离
  164. */
  165. private float spacing(MotionEvent event) {
  166. float x = event.getX(0) - event.getX(1);
  167. float y = event.getY(0) - event.getY(1);
  168. return FloatMath.sqrt(x * x + y * y);
  169. }
  170. /**
  171. * 两点的中点
  172. */
  173. private void midPoint(PointF point, MotionEvent event) {
  174. float x = event.getX(0) + event.getX(1);
  175. float y = event.getY(0) + event.getY(1);
  176. point.set(x / 2, y / 2);
  177. }
  178. }

布局文件需要注意了,使用 <com.example.myimageview.MyImageView></com.example.myimageview.MyImageView>标签,怕一些新手不知道,别怪我啰嗦

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent" >
  5. <com.example.myimageview.MyImageView
  6. android:id="@+id/imageview"
  7. android:layout_width="fill_parent"
  8. android:layout_height="fill_parent"
  9. android:src="@drawable/item" >
  10. </com.example.myimageview.MyImageView>
  11. </RelativeLayout>

新建一个MainActivity咯,

  1. package com.example.myimageview;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. public class MainActivity extends Activity {
  5. @Override
  6. protected void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. setContentView(R.layout.activity_main);
  9. MyImageView myImageView = (MyImageView)findViewById(R.id.imageview);
  10. myImageView.setImageDrawable(getResources().getDrawable(R.drawable.item1));
  11. }
  12. }

项目源码,点击下载

Android 自定义ImageView支持缩放,拖拽,方便复用的更多相关文章

  1. 一款基于jQuery的支持鼠标拖拽滑动焦点图

    记得之前我们分享过一款jQuery全屏广告图片焦点图,图片切换效果还不错.今天我们要分享另外一款jQuery焦点图插件,它的特点是支持鼠标拖拽滑动,所以在移动设备上使用更加方便,你只要用手指滑动屏幕即 ...

  2. wpf图片查看器,支持鼠标滚动缩放拖拽

    最近项目需要,要用到一个图片查看器,类似于windows自带的图片查看器那样,鼠标滚动可以缩放,可以拖拽图片,于是就写了这个简单的图片查看器. 前台代码: <Window x:Class=&qu ...

  3. Android自定义ImageView实现图片圆形 ,椭圆和矩形圆角显示

    Android中的ImageView只能显示矩形的图片,为了用户体验更多,Android实现圆角矩形,圆形或者椭圆等图形,一般通过自定义ImageView来实现,首先获取到图片的Bitmap,然后通过 ...

  4. Android -- 自定义ImageView(圆形头像)

    1.  原图

  5. Android自定义ImageView圆形头像

    效果图: 代码如下: RoundImageView.java import cn.comnav.evaluationsystem.R; import android.content.Context; ...

  6. Linux下安装VMware Tools(使虚拟机支持文件拖拽)

    如图点击虚拟机找到安装VMware Tools选项,点击后会在虚拟机桌面显示一个光盘,双击进入如下页面: 选择压缩包将其复制放入Home中不带中文的文件夹: 打开终端,输入cd命令进入文件夹,将压缩包 ...

  7. Android 单指触控拖拽,两指触控缩放

    import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view. ...

  8. Android 自定义ScrollView 支持惯性滑动,惯性回弹效果。支持上拉加载更多

    先讲下原理: ScrollView的子View 主要分为3部分:head头部,滚动内容,fooder底部 我们实现惯性滑动,以及回弹,都是靠超过head或者fooder 就重新滚动到  ,内容的顶部或 ...

  9. android自定义相册 支持低端机不内存溢出

    1 之前在网上看的自定义相册很多时候在低端机都会内存溢出开始上代码把 首先我们要拿到图片的所有路径 cursor = context.getContentResolver().query( Media ...

随机推荐

  1. QT 遇到的问题

    遇到的问题: 1:在QT中使用opengl,发现一个很神奇的问题,个人感觉是qt的bug. 问题详情:在我添加了一个成员变量之后,使用opengl编写的窗口没有任何输出了,只有一个背景. 但是删除那个 ...

  2. Docker容器学习梳理 - 容器时间跟宿主机时间同步

    在Docker容器创建好之后,可能会发现容器时间跟宿主机时间不一致,这就需要同步它们的时间,让容器时间跟宿主机时间保持一致.如下: 宿主机时间 [root@slave-1 ~]# date Fri M ...

  3. Ceph常规操作及常见问题梳理

    Ceph集群管理 每次用命令启动.重启.停止Ceph守护进程(或整个集群)时,必须指定至少一个选项和一个命令,还可能要指定守护进程类型或具体例程. **命令格式如 {commandline} [opt ...

  4. Python 可调用对象

    除了用户定义的函数,调用运算符(即 ())还可以应用到其他对象上.如果想判断对象能否调用,可以使用内置的 callable() 函数.Python 数据模型文档列出了 7 种可调用对象.(1)用户定义 ...

  5. 回溯法解n皇后问题

    #include<bits/stdc++.h> using namespace std; int n,sum; int c[100]; void search(int cur){ if(c ...

  6. zookeeper安装和使用 windows环境(转)

    原文地址: http://blog.csdn.net/tlk20071/article/details/52028945 简介 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是G ...

  7. 【转】单片机HEX文件完全解读

    转:http://www.eefocus.com/craftor/blog/10-07/193051_8ce59.html Craftor原创,首发于与非网,转载请保留此处. HEX文件,是Intel ...

  8. PAT L2-001 紧急救援

    https://pintia.cn/problem-sets/994805046380707840/problems/994805073643683840 作为一个城市的应急救援队伍的负责人,你有一张 ...

  9. Eclipse: Difference between clean, build and publish

    https://stackoverflow.com/questions/5656989/eclipse-difference-between-clean-build-and-publish http: ...

  10. FreeMarker example all in one

    Pick up from http://demojava.iteye.com/blog/800204