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:具体的效果图


                             

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

http://www.bdqn.cn/news/201304/8794.shtml

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Android平台上,可以使用一些常用的手势操作来实现图片的平移、双指缩放和双击放大缩小。 首先,为了实现平移功能,可以使用触摸事件的ACTION_MOVE来处理手指在屏幕上滑动的操作。通过计算滑动距离,可以改变图片的位置从而实现平移效果。 其次,双指缩放可以使用触摸事件的ACTION_POINTER_DOWN和ACTION_POINTER_UP来追踪并处理触摸屏幕上第二个手指按下和松开的操作。在处理时,可以通过计算两个手指触摸点之间的距离来改变图片的缩放比例,从而实现双指缩放效果。 最后,双击放大缩小可以通过设置一个双击的监听器来实现。在双击监听器的回调方法中,可以根据当前的图片缩放状态来判断是进行放大操作还是缩小操作。并根据需要更改图片的缩放比例,实现双击放大缩小功能。 在实现上述功能时,可以使用Android提供的一些核心类来辅助开发,如View、MotionEvent、GestureDetector等。同时,还可以结合自定义View和动画效果来提升用户体验,使图片的平移、缩放和双击动作更加流畅和自然。 总之,通过合理运用触摸事件、手势识别、双击监听器等技术,可以在Android上实现图片的平移、双指缩放和双击放大缩小功能,从而提升用户与应用程序的交互体验。 ### 回答2: 在Android开发中,可以通过使用ImageView控件来实现对图片的平移、双指缩放和双击放大缩小操作。 1. 平移:可以通过使用Matrix类对ImageView进行变换来实现图片的平移。首先,我们需要为ImageView设置一个OnTouchListener来监听用户的手势操作。在手势操作的回调方法中,可以通过获取手指按下和移动的位置差来计算出需要平移的距离,然后通过设置Matrix的平移矩阵来实现图片的平移效果。 2. 双指缩放:可以通过GestureDetector类来监听双指缩放手势。在手势操作的回调方法中,可以获取到两个手指的起始位置和当前位置,通过计算两个手指之间的距离差来判断缩放的比例。然后,再通过设置Matrix的缩放矩阵来实现图片的缩放效果。需要注意的是,在进行缩放操作时,还需要考虑到手指中心点的位置变化。 3. 双击放大缩小:也可以通过GestureDetector类来监听双击手势。在手势操作的回调方法中,可以判断是否发生了双击事件,并获取到双击的位置。当双击事件发生时,可以通过判断当前图片的缩放比例来决定是放大还是缩小。通过设置Matrix的缩放矩阵和平移矩阵来实现图片放大缩小效果。 需要注意的是,为了实现图片的平移、双指缩放和双击放大缩小操作,我们需要对ImageView进行一系列的监听和处理操作。同时,为了方便管理和控制这些操作,可以将相关的代码封装成一个自定义的图片控件,并在该控件中进行处理。 ### 回答3: Android 提供了多种方法来实现图片的平移、双指缩放和双击放大缩小功能。 首先,要实现图片的平移,我们可以使用 GestureDetector 类。可以通过重写 onScroll() 方法来检测用户的滑动手势,然后将图片的位置进行相应的调整,从而实现平移效果。 其次,要实现双指缩放功能,我们可以借助 ScaleGestureDetector 类。通过重写 onScale() 方法,我们可以获取用户的缩放手势,并根据手势的缩放比例调整图片的尺寸,从而实现双指缩放的效果。 最后,要实现双击放大缩小功能,我们可以使用 GestureDetector 类。可以通过重写 onDoubleTap() 方法来检测用户的双击手势,然后根据当前图片的尺寸和双击事件的位置,来判断是进行放大还是缩小操作,最后将图片的尺寸进行相应的调整,实现双击放大缩小的效果。 需要注意的是,以上的功能实现是基于 Android 的原生 API,还有其他第三方库也提供了更便捷的方法来实现这些功能,例如 PhotoView 库,它提供了更多灵活的选项和交互效果,可以更加方便地实现图片的平移、缩放和双击操作。 综上所述,Android 针对图片的平移、双指缩放和双击放大缩小,可以通过重写相应的手势监听方法或使用第三方库来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值