今天刚发了一篇关于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. json模块 & pickle模块

    之前学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了,所 ...

  2. 分布式监控系统Zabbix-图形集中展示插件Graphtree安装笔记

    Zabbix想要集中展示图像,唯一的选择是screen,后来zatree解决了screen的问题,但性能不够好.Graphtree 由OneOaaS开发并开源出来,用来解决Zabbix的图形展示问题, ...

  3. nginx日志格式字段

    Nginx日志主要分为两种:访问日志和错误日志.日志开关在Nginx配置文件(/etc/nginx/nginx.conf)中设置,两种日志都可以选择性关闭,默认都是打开的. 访问日志 访问日志主要记录 ...

  4. [LeetCode] 307. Range Sum Query - Mutable 解题思路

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

  5. CF 1047 C. Enlarge GCD

    传送门 [http://codeforces.com/contest/1047/problem/C] 题意 给你n个数,移除最少的数字使剩下的数字GCD大于初始GCD 思路 需要一点暴力的技巧,先求出 ...

  6. 剑值offer:最小的k个数

    这是在面试常遇到的topk问题. 题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 解题思路: 思路一:用快排对数 ...

  7. 续摄影O2O篇

    项目名:摄影O2O 工具:Eclipse ,adt,jdk1.8,MySQL 步骤:(一) 1.导入beauty项目到一个adt中,然后创建模拟器,运行(客户端) 2.导入SocketSever项目到 ...

  8. 爬虫时http错误提示

    在爬虫,请求网站的时候,有时候出现域名报错,所出现的代码所对应的意思:

  9. MapReduce 过程详解

    Hadoop 越来越火, 围绕Hadoop的子项目更是增长迅速, 光Apache官网上列出来的就十几个, 但是万变不离其宗, 大部分项目都是基于Hadoop common MapReduce 更是核心 ...

  10. PAT 1061 判断题

    https://pintia.cn/problem-sets/994805260223102976/problems/994805268817231872 判断题的评判很简单,本题就要求你写个简单的程 ...