2
2
3
3
import android .app .Activity ;
4
4
import android .app .AlertDialog ;
5
- import android .content .Context ;
6
5
import android .content .DialogInterface ;
7
6
import android .content .Intent ;
8
7
import android .graphics .Bitmap ;
12
11
import android .os .Environment ;
13
12
import android .view .MotionEvent ;
14
13
import android .view .View ;
14
+ import android .view .ViewConfiguration ;
15
15
import android .view .ViewGroup ;
16
16
import android .view .Window ;
17
17
import android .widget .FrameLayout ;
27
27
import cn .forward .androids .utils .ThreadUtil ;
28
28
29
29
/**
30
+ * 涂鸦界面,根据GraffitiView的接口,提供页面交互
31
+ * (这边代码和ui比较粗糙,主要目的是告诉大家GraffitiView的接口具体能实现什么功能,实际需求中的ui和交互需另提别论)
30
32
* Created by huangziwei on 2016/9/3.
31
33
*/
32
34
public class GraffitiActivity extends Activity {
33
35
34
36
35
37
/**
36
38
* 启动涂鸦界面
39
+ *
37
40
* @param activity
38
- * @param imagePath 图片路径
41
+ * @param imagePath 图片路径
39
42
* @param requestCode startActivityForResult的请求码
40
43
*/
41
44
public static void startActivityForResult (Activity activity , String imagePath , int requestCode ) {
@@ -62,16 +65,25 @@ public static void startActivityForResult(Activity activity, String imagePath, i
62
65
private int mTouchMode ;
63
66
private boolean mIsMovingPic = false ;
64
67
65
- private float mOldDist , mNewDist , mToucheCentreXOnGraffiti ,
68
+ // 手势操作相关
69
+ private float mOldScale , mOldDist , mNewDist , mToucheCentreXOnGraffiti ,
66
70
mToucheCentreYOnGraffiti , mTouchCentreX , mTouchCentreY ;// 双指距离
71
+
67
72
private float mTouchLastX , mTouchLastY ;
68
73
69
74
private boolean mIsScaling = false ;
70
75
private float mScale = 1 ;
71
- private final float mMaxScale = 3.5f ;
72
- private final int TIME_SPAN = 80 ;
76
+ private final float mMaxScale = 3.5f ; // 最大缩放倍数
77
+ private final float mMinScale = 0.25f ; // 最小缩放倍数
78
+ private final int TIME_SPAN = 40 ;
73
79
private View mBtnMovePic ;
74
80
81
+ private int mTouchSlop ;
82
+
83
+ // 当前屏幕中心点对应在GraffitiView中的点的坐标
84
+ float mCenterXOnGraffiti ;
85
+ float mCenterYOnGraffiti ;
86
+
75
87
@ Override
76
88
public void onCreate (Bundle savedInstanceState ) {
77
89
super .onCreate (savedInstanceState );
@@ -127,12 +139,7 @@ public void onError(int i, String msg) {
127
139
});
128
140
mFrameLayout .addView (mGraffitiView , ViewGroup .LayoutParams .MATCH_PARENT , ViewGroup .LayoutParams .MATCH_PARENT );
129
141
mOnClickListener = new GraffitiOnClickListener ();
130
-
131
- mUpdateScale = new Runnable () {
132
- public void run () {
133
- mGraffitiView .setScale (mScale );
134
- }
135
- };
142
+ mTouchSlop = ViewConfiguration .get (getApplicationContext ()).getScaledTouchSlop ();
136
143
initView ();
137
144
}
138
145
@@ -223,19 +230,19 @@ public boolean onTouch(View v, MotionEvent event) {
223
230
mTouchLastY = event .getY ();
224
231
} else { // 多点
225
232
mNewDist = spacing (event );// 两点滑动时的距离
226
- if (Math .abs (mNewDist - mOldDist ) >= 2000 ) {
227
- if (mNewDist - mOldDist > 0 ) {// 拉大
228
- mScale += 0.05f ;
229
- if (mScale > mMaxScale ) {
230
- mScale = mMaxScale ;
231
- }
232
- } else {// 拉小
233
- mScale -= 0.05f ;
234
- if (mScale < 0.5f ) {
235
- mScale = 0.5f ;
236
- }
233
+ if (Math .abs (mNewDist - mOldDist ) >= mTouchSlop ) {
234
+ float scale = mNewDist / mOldDist ;
235
+ mScale = mOldScale * scale ;
236
+
237
+ if (mScale > mMaxScale ) {
238
+ mScale = mMaxScale ;
237
239
}
240
+ if (mScale < mMinScale ) { // 最小倍数
241
+ mScale = mMinScale ;
242
+ }
243
+ // 围绕坐标(0,0)缩放图片
238
244
mGraffitiView .setScale (mScale );
245
+ // 缩放后,偏移图片,以产生围绕某个点缩放的效果
239
246
float transX = mGraffitiView .toTransX (mTouchCentreX , mToucheCentreXOnGraffiti );
240
247
float transY = mGraffitiView .toTransY (mTouchCentreY , mToucheCentreYOnGraffiti );
241
248
mGraffitiView .setTrans (transX , transY );
@@ -247,6 +254,7 @@ public boolean onTouch(View v, MotionEvent event) {
247
254
return true ;
248
255
case MotionEvent .ACTION_POINTER_DOWN :
249
256
mTouchMode += 1 ;
257
+ mOldScale = mGraffitiView .getScale ();
250
258
mOldDist = spacing (event );// 两点按下时的距离
251
259
mTouchCentreX = (event .getX (0 ) + event .getX (1 )) / 2 ;// 不用减trans
252
260
mTouchCentreY = (event .getY (0 ) + event .getY (1 )) / 2 ;
@@ -269,7 +277,7 @@ public boolean onTouch(View v, MotionEvent event) {
269
277
private float spacing (MotionEvent event ) {
270
278
float x = event .getX (0 ) - event .getX (1 );
271
279
float y = event .getY (0 ) - event .getY (1 );
272
- return x * x + y * y ;
280
+ return ( float ) Math . sqrt ( x * x + y * y ) ;
273
281
}
274
282
275
283
private class GraffitiOnClickListener implements View .OnClickListener {
@@ -443,11 +451,16 @@ public void scalePic(View v) {
443
451
return ;
444
452
mIsScaling = true ;
445
453
mScale = mGraffitiView .getScale ();
446
- if (v .getId () == R .id .btn_amplifier ) {
454
+
455
+ // 确定当前屏幕中心点对应在GraffitiView中的点的坐标,之后将围绕这个点缩放
456
+ mCenterXOnGraffiti = mGraffitiView .toX (mGraffitiView .getWidth () / 2 );
457
+ mCenterYOnGraffiti = mGraffitiView .toY (mGraffitiView .getHeight () / 2 );
458
+
459
+ if (v .getId () == R .id .btn_amplifier ) { // 放大
447
460
ThreadUtil .getInstance ().runOnAsyncThread (new Runnable () {
448
461
public void run () {
449
462
do {
450
- mScale += 0.1f ;
463
+ mScale += 0.05f ;
451
464
if (mScale > mMaxScale ) {
452
465
mScale = mMaxScale ;
453
466
mIsScaling = false ;
@@ -462,13 +475,13 @@ public void run() {
462
475
463
476
}
464
477
});
465
- } else if (v .getId () == R .id .btn_reduce ) {
478
+ } else if (v .getId () == R .id .btn_reduce ) { // 缩小
466
479
ThreadUtil .getInstance ().runOnAsyncThread (new Runnable () {
467
480
public void run () {
468
481
do {
469
- mScale -= 0.1f ;
470
- if (mScale < 0.5f ) {
471
- mScale = 0.5f ;
482
+ mScale -= 0.05f ;
483
+ if (mScale < mMinScale ) {
484
+ mScale = mMinScale ;
472
485
mIsScaling = false ;
473
486
}
474
487
updateScale ();
@@ -484,6 +497,19 @@ public void run() {
484
497
}
485
498
486
499
private void updateScale () {
500
+ if (mUpdateScale == null ) {
501
+
502
+ mUpdateScale = new Runnable () {
503
+ public void run () {
504
+ // 围绕坐标(0,0)缩放图片
505
+ mGraffitiView .setScale (mScale );
506
+ // 缩放后,偏移图片,以产生围绕某个点缩放的效果
507
+ float transX = mGraffitiView .toTransX (mGraffitiView .getWidth () / 2 , mCenterXOnGraffiti );
508
+ float transY = mGraffitiView .toTransY (mGraffitiView .getHeight () / 2 , mCenterYOnGraffiti );
509
+ mGraffitiView .setTrans (transX , transY );
510
+ }
511
+ };
512
+ }
487
513
ThreadUtil .getInstance ().runOnMainThread (mUpdateScale );
488
514
}
489
515
}
0 commit comments