Android 自定义ImageView支持缩放,拖拽,方便复用

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

[java] view plaincopy

  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>标签,怕一些新手不知道,别怪我啰嗦

[html] view plaincopy

  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咯,

[java] view plaincopy

  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. }

项目源码,点击下载

时间: 2024-12-25 11:37:14

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

Android多点触控缩放拖拽实例

在Android上查看图片或者浏览网页时,我们往往有把图片或者网页放大或者缩小的的需求,这样就能够获得更多的细节信息 或者获得更多的全貌信息,多点触摸与绽放功能正是满足这种应用场景的技术. 下面通过一个例子来学习实现图片的拖拉功能: 程序运行示意图:1.初始化界面  2.为缩小的界面  3.为放大的界面            新建一个名称为DragAndDrop的Android工程,目录结构如下: 主界面的activity_layout.xml的布局代码如下: <RelativeLayout x

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

记得之前我们分享过一款jQuery全屏广告图片焦点图,图片切换效果还不错.今天我们要分享另外一款jQuery焦点图插件,它的特点是支持鼠标拖拽滑动,所以在移动设备上使用更加方便,你只要用手指滑动屏幕即可切换图片. 在线预览   源码下载 实现的代码. html代码: <div class="main_visual"> <div class="flicking_con"> <a class="on" href=&quo

自定义视图之————安卓图库缩放拖拽的完整实现

加了大部分注释,看注释应该可以明白基本的思路.欢迎大神留言拍砖,此文适合小白观看. package com.example.imagedeal; import android.content.Context; import android.graphics.Matrix; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.util.AttributeSet; impor

Android自定义imageview可对图片进行多点缩放和拖动

package com.msstudent.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; i

自定义ImageVIew 支持手势 拖动、缩放、旋转

import android.content.Context; import android.graphics.Matrix; import android.graphics.PointF; import android.util.AttributeSet; import android.util.FloatMath; import android.view.MotionEvent; import android.widget.ImageView; public class ImageTouch

Android 自定义ImageView实现圆角/圆形 附加OnTouchListener详细注释以及Button圆角

转载请注明出处:王亟亟的大牛之路 平时要用一些非方方正正的按钮之类的小伙伴们是如何实现的?RadioButton?ImageButton?还是其他? 今天亟亟上的是ImageView来实现的 先上下效果图(目录结构) 分析: shape.xml用于Button的"倒角"(做过机械类的都懂,哈哈) attr.xml用于自定义ImageView的标签的定义 ids.xml用于控件findbyid用,为什么补+id 等会我会来解释 效果图: 分析:一个Button 2个自定义ImageVie

Android 贝塞尔曲线实现QQ拖拽清除效果

纯属好奇心驱动写的一个学习性Demo,效果如下: 这个小功能最重要的点在于起始点和触摸点之间的连接线绘制,它并不是一条单纯的直线,而是中间细两头粗的一条不规则的Path,而这个中间向内弯曲的效果正是一条贝塞尔曲线,中间这个Path是由两条贝塞尔曲线和两条直线组成.看下图: 两个带圆弧的线就是由三点确认的一个贝塞尔曲线: 在Android已经有提供画贝塞尔曲线的接口,三个点传进去,效果就出来了. 贝塞尔曲线是用三个或多个点来确定的一条曲线,它在图形图像学中有相当重要的地位,Path中也提供了一些方

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

Android中的ImageView只能显示矩形的图片,为了用户体验更多,Android实现圆角矩形,圆形或者椭圆等图形,一般通过自定义ImageView来实现,首先获取到图片的Bitmap,然后通过Paint和onDraw()进行圆形图片显示. 效果图: 代码: 1 activity_image.xml 2 <?xml version="1.0" encoding="utf-8"?> 3 <LinearLayoutxmlns:android=&q

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

1.  原图      -->    2.  自定义的控件类 package com.chaowen.yixin; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Pa