今天刚发了一篇关于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. PMO在组织中实现价值应做的工作

    PMO在组织中实现价值应做的工作 研发人员及项目经理常常对PMO有反感情绪,认为其不熟悉业务流程与技术.经常要求项目经理和研发人员提交形式化的材料,只审批和监控,不能为项目提供良好的服务.在很多企业, ...

  2. 结对项目 Pair Project

    结对项目 Pair Project 一人编程,一人操作,共同检查. 源码 https://github.com/dpch16303/test/blob/master/%E5%AE%9E%E8%B7%B ...

  3. 结对项目junit测试用例

    题目:我们假设我们要写一个整数除法的类,并且给他写测试用例. 结对分工:滕娟负责写代码,搜集资料,整理,潘广玫负责进行测试,处理测试结果 github地址链接: https://github.com/ ...

  4. Leetcode 546. Remove Boxes

    题目链接: https://leetcode.com/problems/remove-boxes/description/ 问题描述 若干个有序排列的box和它们的颜色,每次可以移除若干个连续的颜色相 ...

  5. Redis持久化的两种方式和区别

    该文转载自:http://www.cnblogs.com/swyi/p/6093763.html Redis持久化的两种方式和区别 Redis是一种高级key-value数据库.它跟memcached ...

  6. Socket、Session、Option和Pipe

    消息队列NetMQ 原理分析4-Socket.Session.Option和Pipe   消息队列NetMQ 原理分析4-Socket.Session.Option和Pipe 前言 介绍 目的 Soc ...

  7. Golang的panic和recover

    panic 关键字panic的作用是制造一次宕机,宕机就代表程序运行终止,但是已经“生效”的延迟函数仍会执行(即已经压入栈的defer延迟函数,panic之前的). 为什么要制造宕机呢?是因为宕机不容 ...

  8. Zabbix的简单使用

    0. 卸载mariadb 安装mysql 方法 rpm -qa |grep mariadb 然后 rpm -e --nodeps mariadb***** 安装mysql # 下载mysql源安装包 ...

  9. 无返回值的异步方法能否不用await

    1.无返回值的异步方法能否不用await? 如果你不需要等待加一的操作完成,那就可以直接执行后面的操作.那要看你的需求了,如果你后面的操作必须在加一的操作后执行,那就要await了 2.请问C#中如何 ...

  10. JavaScript——AJAX

    AJAX技术是网页构建的必备技能之一,本文希望能帮助大家轻松的学习这项技术 一.什么是ajax? ajax(异步javascript xml) 能够刷新局部网页数据而不是重新加载整个网页. 二.如何使 ...