android Matrix图片随意的放大缩小,拖动


摘要:step1:新建一个项目DragAndZoom,并准备一张照片放在res/drawable-hdpi目录下,如下图所示:

step1:新建一个项目DragAndZoom,并准备一张照片放在res/drawable-hdpi目录下,如下图所示:

  

step2: 设置应用的UI界面,在main.xml中设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version= "1.0"  encoding= "utf-8" ?>
<LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
     android:orientation= "vertical"
     android:layout_width= "fill_parent"
     android:layout_height= "fill_parent"
     >
<ImageView 
     android:layout_width= "fill_parent"
     android:layout_height= "wrap_content"
     android:src= "@drawable/wall"
     android:id= "@+id/imageView"
     android:scaleType= "matrix" 
     />  <!-- 指定为matrix类型 -->
</LinearLayout>

step3:MainActivity.java中实现具体的需求


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package  cn.roco.drag;
  
import  android.app.Activity;
import  android.graphics.Matrix;
import  android.graphics.PointF;
import  android.os.Bundle;
import  android.util.FloatMath;
import  android.view.MotionEvent;
import  android.view.View;
import  android.view.View.OnTouchListener;
import  android.widget.ImageView;
  
public  class  MainActivity  extends  Activity {
  
     private  ImageView imageView;
  
     @Override
     public  void  onCreate(Bundle savedInstanceState) {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.main);
  
         imageView = (ImageView)  this .findViewById(R.id.imageView);
         imageView.setOnTouchListener( new  TouchListener());
     }
  
     private  final  class  TouchListener  implements  OnTouchListener {
          
         /** 记录是拖拉照片模式还是放大缩小照片模式 */
         private  int  mode =  0 ; // 初始状态 
         /** 拖拉照片模式 */
         private  static  final  int  MODE_DRAG =  1 ;
         /** 放大缩小照片模式 */
         private  static  final  int  MODE_ZOOM =  2 ;
          
         /** 用于记录开始时候的坐标位置 */
         private  PointF startPoint =  new  PointF();
         /** 用于记录拖拉图片移动的坐标位置 */
         private  Matrix matrix =  new  Matrix();
         /** 用于记录图片要进行拖拉时候的坐标位置 */
         private  Matrix currentMatrix =  new  Matrix();
      
         /** 两个手指的开始距离 */
         private  float startDis;
         /** 两个手指的中间点 */
         private  PointF midPoint;
  
         @Override
         public  boolean onTouch(View v, MotionEvent event) {
             /** 通过与运算保留最后八位 MotionEvent.ACTION_MASK = 255 */
             switch  (event.getAction() & MotionEvent.ACTION_MASK) {
             // 手指压下屏幕
             case  MotionEvent.ACTION_DOWN:
                 mode = MODE_DRAG;
                 // 记录ImageView当前的移动位置
                 currentMatrix. set (imageView.getImageMatrix());
                 startPoint. set (event.getX(), event.getY());
                 break ;
             // 手指在屏幕上移动,改事件会被不断触发
             case  MotionEvent.ACTION_MOVE:
                 // 拖拉图片
                 if  (mode == MODE_DRAG) {
                     float dx = event.getX() - startPoint.x;  // 得到x轴的移动距离
                     float dy = event.getY() - startPoint.y;  // 得到x轴的移动距离
                     // 在没有移动之前的位置上进行移动
                     matrix. set (currentMatrix);
                     matrix.postTranslate(dx, dy);
                 }
                 // 放大缩小图片
                 else  if  (mode == MODE_ZOOM) {
                     float endDis = distance(event); // 结束距离
                     if  (endDis > 10f) {  // 两个手指并拢在一起的时候像素大于10
                         float scale = endDis / startDis; // 得到缩放倍数
                         matrix. set (currentMatrix);
                         matrix.postScale(scale, scale,midPoint.x,midPoint.y);
                     }
                 }
                 break ;
             // 手指离开屏幕
             case  MotionEvent.ACTION_UP:
                 // 当触点离开屏幕,但是屏幕上还有触点(手指)
             case  MotionEvent.ACTION_POINTER_UP:
                 mode =  0 ;
                 break ;
             // 当屏幕上已经有触点(手指),再有一个触点压下屏幕
             case  MotionEvent.ACTION_POINTER_DOWN:
                 mode = MODE_ZOOM;
                 /** 计算两个手指间的距离 */
                 startDis = distance(event);
                 /** 计算两个手指间的中间点 */
                 if  (startDis > 10f) {  // 两个手指并拢在一起的时候像素大于10
                     midPoint = mid(event);
                     //记录当前ImageView的缩放倍数
                     currentMatrix. set (imageView.getImageMatrix());
                 }
                 break ;
             }
             imageView.setImageMatrix(matrix);
             return  true ;
         }
  
         /** 计算两个手指间的距离 */
         private  float distance(MotionEvent event) {
             float dx = event.getX( 1 ) - event.getX( 0 );
             float dy = event.getY( 1 ) - event.getY( 0 );
             /** 使用勾股定理返回两点之间的距离 */
             return  FloatMath.sqrt(dx * dx + dy * dy);
         }
  
         /** 计算两个手指间的中间点 */
         private  PointF mid(MotionEvent event) {
             float midX = (event.getX( 1 ) + event.getX( 0 )) /  2 ;
             float midY = (event.getY( 1 ) + event.getY( 0 )) /  2 ;
             return  new  PointF(midX, midY);
         }
  
     }
  
}

step4:AndroidMainfest.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version= "1.0"  encoding= "utf-8" ?>
<manifest xmlns:android= "http://schemas.android.com/apk/res/android"
       package = "cn.roco.drag"
       android:versionCode= "1"
       android:versionName= "1.0" >
     <uses-sdk android:minSdkVersion= "8"  />
  
     <application android:icon= "@drawable/icon" android: label = "@string/app_name" >
         <activity android:name= ".MainActivity"
                   android: label = "@string/app_name" >
             <intent-filter>
                 <action android:name= "android.intent.action.MAIN"  />
                 <category android:name= "android.intent.category.LAUNCHER"  />
             </intent-filter>
         </activity>
  
     </application>
</manifest>

step5:具体的效果图


                             

上面两个是图片拖拽的效果,而图片的缩放效果要在真机中才能够看得到,请读者自己在真机环境中测试。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值