通過手勢實現Android ImageView 縮放
方法一:
將以下程式碼寫到MulitPointTouchListener.java中,然後對你相應的圖片進行OnTouchListener。
例如:imageView.setOnTouchListener(new MulitPointTouchListener ());
在xml中要將ImageView的縮放格式改成Matrix
例如:android:scaleType="matrix"
這樣就可以實現圖片的縮放了
下面是MulitPointTouchListener.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
|
public
class
MulitPointTouchListener implements
OnTouchListener { private
static
final
String TAG = "Touch" ; //
These matrices will be used to move and zoom image Matrix
matrix = new
Matrix(); Matrix
savedMatrix = new
Matrix(); //
We can be in one of these 3 states static
final
int
NONE = 0 ; static
final
int
DRAG = 1 ; static
final
int
ZOOM = 2 ; int
mode = NONE; //
Remember some things for zooming PointF
start = new
PointF(); PointF
mid = new
PointF(); float
oldDist = 1f; @Override public
boolean
onTouch(View v, MotionEvent event) { ImageView
view = (ImageView) v; //
Log.e("view_width", //
view.getImageMatrix()..toString()+"*"+v.getWidth()); //
Dump touch event to log dumpEvent(event); //
Handle touch events here... switch
(event.getAction() & MotionEvent.ACTION_MASK) { case
MotionEvent.ACTION_DOWN: matrix.set(view.getImageMatrix()); savedMatrix.set(matrix); start.set(event.getX(),
event.getY()); //Log.d(TAG,
"mode=DRAG"); mode
= DRAG; //Log.d(TAG,
"mode=NONE"); break ; case
MotionEvent.ACTION_POINTER_DOWN: oldDist
= spacing(event); //Log.d(TAG,
"oldDist=" + oldDist); if
(oldDist > 10f) { savedMatrix.set(matrix); midPoint(mid,
event); mode
= ZOOM; //Log.d(TAG,
"mode=ZOOM"); } break ; case
MotionEvent.ACTION_UP: case
MotionEvent.ACTION_POINTER_UP: mode
= NONE; //Log.e("view.getWidth",
view.getWidth() + ""); //Log.e("view.getHeight",
view.getHeight() + ""); break ; case
MotionEvent.ACTION_MOVE: if
(mode == DRAG) { //
... matrix.set(savedMatrix); matrix.postTranslate(event.getX()
- start.x, event.getY() -
start.y); } else
if
(mode == ZOOM) { float
newDist = spacing(event); //Log.d(TAG,
"newDist=" + newDist); if
(newDist > 10f) { matrix.set(savedMatrix); float
scale = newDist / oldDist; matrix.postScale(scale,
scale, mid.x, mid.y); } } break ; } view.setImageMatrix(matrix); return
true ; //
indicate event was handled } private
void
dumpEvent(MotionEvent event) { String
names[] = { "DOWN" , "UP" , "MOVE" , "CANCEL" , "OUTSIDE" , "POINTER_DOWN" , "POINTER_UP" , "7?" , "8?" , "9?"
}; StringBuilder
sb = new
StringBuilder(); int
action = event.getAction(); int
actionCode = action & MotionEvent.ACTION_MASK; sb.append( "event
ACTION_" ).append(names[actionCode]); if
(actionCode == MotionEvent.ACTION_POINTER_DOWN ||
actionCode == MotionEvent.ACTION_POINTER_UP) { sb.append( "(pid
" ).append( action
>> MotionEvent.ACTION_POINTER_ID_SHIFT); sb.append( ")" ); } sb.append( "[" ); for
( int
i = 0 ;
i < event.getPointerCount(); i++) { sb.append( "#" ).append(i); sb.append( "(pid
" ).append(event.getPointerId(i)); sb.append( ")=" ).append(( int )
event.getX(i)); sb.append( "," ).append(( int )
event.getY(i)); if
(i + 1
< event.getPointerCount()) sb.append( ";" ); } sb.append( "]" ); //Log.d(TAG,
sb.toString()); } private
float
spacing(MotionEvent event) { float
x = event.getX( 0 )
- event.getX( 1 ); float
y = event.getY( 0 )
- event.getY( 1 ); return
FloatMath.sqrt(x * x + y * y); } private
void
midPoint(PointF point, MotionEvent event) { float
x = event.getX( 0 )
+ event.getX( 1 ); float
y = event.getY( 0 )
+ event.getY( 1 ); point.set(x
/ 2 ,
y / 2 ); } } |
方法二:自定義一個ImageView,例如TouchImageView:
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
|
import
android.content.Context; import
android.graphics.Matrix; import
android.graphics.PointF; import
android.graphics.drawable.Drawable; import
android.util.AttributeSet; import
android.util.Log; import
android.view.MotionEvent; import
android.view.ScaleGestureDetector; import
android.view.View; import
android.widget.ImageView; public
class
TouchImageView extends
ImageView { Matrix
matrix; //
We can be in one of these 3 states static
final
int
NONE = 0 ; static
final
int
DRAG = 1 ; static
final
int
ZOOM = 2 ; int
mode = NONE; //
Remember some things for zooming PointF
last = new
PointF(); PointF
start = new
PointF(); float
minScale = 1f; float
maxScale = 3f; float []
m; int
viewWidth, viewHeight; static
final
int
CLICK = 3 ; float
saveScale = 1f; protected
float
origWidth, origHeight; int
oldMeasuredWidth, oldMeasuredHeight; ScaleGestureDetector
mScaleDetector; Context
context; public
TouchImageView(Context context) { super (context); sharedConstructing(context); } public
TouchImageView(Context context, AttributeSet attrs) { super (context,
attrs); sharedConstructing(context); } private
void
sharedConstructing(Context context) { super .setClickable( true ); this .context
= context; mScaleDetector
= new
ScaleGestureDetector(context, new
ScaleListener()); matrix
= new
Matrix(); m
= new
float [ 9 ]; setImageMatrix(matrix); setScaleType(ScaleType.MATRIX); setOnTouchListener( new
OnTouchListener() { @Override public
boolean
onTouch(View v, MotionEvent event) { mScaleDetector.onTouchEvent(event); PointF
curr = new
PointF(event.getX(), event.getY()); switch
(event.getAction()) { case
MotionEvent.ACTION_DOWN: last.set(curr); start.set(last); mode
= DRAG; break ; case
MotionEvent.ACTION_MOVE: if
(mode == DRAG) { float
deltaX = curr.x - last.x; float
deltaY = curr.y - last.y; float
fixTransX = getFixDragTrans(deltaX, viewWidth, origWidth * saveScale); float
fixTransY = getFixDragTrans(deltaY, viewHeight, origHeight * saveScale); matrix.postTranslate(fixTransX,
fixTransY); fixTrans(); last.set(curr.x,
curr.y); } break ; case
MotionEvent.ACTION_UP: mode
= NONE; int
xDiff = ( int )
Math.abs(curr.x - start.x); int
yDiff = ( int )
Math.abs(curr.y - start.y); if
(xDiff < CLICK && yDiff < CLICK) performClick(); break ; case
MotionEvent.ACTION_POINTER_UP: mode
= NONE; break ; } setImageMatrix(matrix); invalidate(); return
true ; //
indicate event was handled } }); } public
void
setMaxZoom( float
x) { maxScale
= x; } private
class
ScaleListener extends
ScaleGestureDetector.SimpleOnScaleGestureListener { @Override public
boolean
onScaleBegin(ScaleGestureDetector detector) { mode
= ZOOM; return
true ; } @Override public
boolean
onScale(ScaleGestureDetector detector) { float
mScaleFactor = detector.getScaleFactor(); float
origScale = saveScale; saveScale
*= mScaleFactor; if
(saveScale > maxScale) { saveScale
= maxScale; mScaleFactor
= maxScale / origScale; } else
if
(saveScale < minScale) { saveScale
= minScale; mScaleFactor
= minScale / origScale; } if
(origWidth * saveScale <= viewWidth || origHeight * saveScale <= viewHeight) matrix.postScale(mScaleFactor,
mScaleFactor, viewWidth / 2 ,
viewHeight / 2 ); else matrix.postScale(mScaleFactor,
mScaleFactor, detector.getFocusX(), detector.getFocusY()); fixTrans(); return
true ; } } void
fixTrans() { matrix.getValues(m); float
transX = m[Matrix.MTRANS_X]; float
transY = m[Matrix.MTRANS_Y]; float
fixTransX = getFixTrans(transX, viewWidth, origWidth * saveScale); float
fixTransY = getFixTrans(transY, viewHeight, origHeight * saveScale); if
(fixTransX != 0
|| fixTransY != 0 ) matrix.postTranslate(fixTransX,
fixTransY); } float
getFixTrans( float
trans, float
viewSize, float
contentSize) { float
minTrans, maxTrans; if
(contentSize <= viewSize) { minTrans
= 0 ; maxTrans
= viewSize - contentSize; } else
{ minTrans
= viewSize - contentSize; maxTrans
= 0 ; } if
(trans < minTrans) return
-trans + minTrans; if
(trans > maxTrans) return
-trans + maxTrans; return
0 ; } float
getFixDragTrans( float
delta, float
viewSize, float
contentSize) { if
(contentSize <= viewSize) { return
0 ; } return
delta; } @Override protected
void
onMeasure( int
widthMeasureSpec, int
heightMeasureSpec) { super .onMeasure(widthMeasureSpec,
heightMeasureSpec); viewWidth
= MeasureSpec.getSize(widthMeasureSpec); viewHeight
= MeasureSpec.getSize(heightMeasureSpec); // //
Rescales image on rotation // if
(oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight ||
viewWidth == 0
|| viewHeight == 0 ) return ; oldMeasuredHeight
= viewHeight; oldMeasuredWidth
= viewWidth; if
(saveScale == 1 )
{ //Fit
to screen. float
scale; Drawable
drawable = getDrawable(); if
(drawable == null
|| drawable.getIntrinsicWidth() == 0
|| drawable.getIntrinsicHeight() == 0 ) return ; int
bmWidth = drawable.getIntrinsicWidth(); int
bmHeight = drawable.getIntrinsicHeight(); Log.d( "bmSize" , "bmWidth:
"
+ bmWidth + "
bmHeight : "
+ bmHeight); float
scaleX = ( float )
viewWidth / ( float )
bmWidth; float
scaleY = ( float )
viewHeight / ( float )
bmHeight; scale
= Math.min(scaleX, scaleY); matrix.setScale(scale,
scale); //
Center the image float
redundantYSpace = ( float )
viewHeight - (scale * ( float )
bmHeight); float
redundantXSpace = ( float )
viewWidth - (scale * ( float )
bmWidth); redundantYSpace
/= ( float ) 2 ; redundantXSpace
/= ( float ) 2 ; matrix.postTranslate(redundantXSpace,
redundantYSpace); origWidth
= viewWidth - 2
* redundantXSpace; origHeight
= viewHeight - 2
* redundantYSpace; setImageMatrix(matrix); } fixTrans(); } } |
然後在我們的Activity中就可以直接使用了:
1
2
3
4
5
6
7
8
9
10
11
|
public
class
TouchImageViewActivity extends
Activity { /**
Called when the activity is first created. */ @Override public
void
onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.main); TouchImageView
img = (TouchImageView) findViewById(R.id.snoop); img.setImageResource(R.drawable.snoopy); img.setMaxZoom(4f); } }
|
相關文章
- Android:ImageView圖片縮放、居中AndroidView
- android imageview 縮放檢視圖片AndroidView
- Android 可平移,縮放,旋轉的ImageViewAndroidView
- android 自定義ImageView實現圖片手勢滑動,多點觸控放大縮小效果AndroidView
- 使用RxJava實現ImageView的拖動、旋轉和縮放RxJavaView
- js實現移動端圖片預覽:手勢縮放, 手勢拖動,雙擊放大...JS
- 實現圖片縮放
- Android 圓角、圓形 ImageView 實現AndroidView
- 圖片操作系列 —(1)手勢縮放圖片功能
- iOS手勢識別的詳細使用(拖動,縮放,旋轉,點選,手勢依賴,自定義手勢)iOS
- iOS手勢識別的詳細使用:拖動、縮放、旋轉、點選、手勢依賴、自定義手勢iOS
- 手機端上傳照片實現 壓縮、拖放、縮放、裁剪、合成拼圖等功能
- Android 中實現圖片平移、縮放、旋轉同步進行Android
- 手把手教你打造支援手勢放大縮小的ImageViewView
- Android通過WindowManager實現懸浮框Android
- Android 通過JNI實現守護程式Android
- Android 圖片縮放Android
- android 拖拽與縮放Android
- Android圖片壓縮實現過程及程式碼Android
- Android通過startService實現批量下載示例Android
- Android通過繼承Binder類實現多程式通訊Android繼承
- ARFoundation - 實現物體旋轉, 平移,縮放
- 滑鼠懸浮圖片實現縮放效果
- JS實現等比例縮放圖片JS
- Android 呼叫相簿 拍照 實現系統控制元件縮放 切割圖片Android控制元件
- 通過佇列實現棧OR通過棧實現佇列佇列
- QLabel顯示圖片 ,並實現縮放
- 利用javascript實現圖片等比例縮放JavaScript
- 視覺化學習:WebGL實現縮放平移視覺化Web
- 圓形 ImageView 的實現方法View
- WPF實現手勢解鎖
- Abp 實現通過手機號註冊使用者
- Android通過Chronometer控制元件實現計時功能Android控制元件
- android實現app通過jni呼叫C/C++方法AndroidAPPC++
- 通過模板實現POI
- Android使用RecycleView實現魅族手機通訊錄介面AndroidView
- canvas實現的圖片縮放程式碼例項Canvas
- Android中通過Messenger與Service實現程式間雙向通訊AndroidMessenger