1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="fill_parent"
4 android:layout_height="fill_parent"
5 android:background="@drawable/bkg_img_default"
6 android:gravity="center"
7 android:orientation="vertical" >
8
9 <LinearLayout
10 android:layout_width="wrap_content"
11 android:layout_height="wrap_content"
12 android:orientation="vertical" >
13
14 <LinearLayout
15 android:layout_width="wrap_content"
16 android:layout_height="wrap_content"
17 android:orientation="horizontal" >
18
19 <LinearLayout
20 android:layout_width="wrap_content"
21 android:layout_height="wrap_content"
22 android:orientation="vertical" >
23
24 <com.ljp.ani.MyImageView
25 android:id="@+id/c_joke"
26 android:layout_width="wrap_content"
27 android:layout_height="wrap_content"
28 android:layout_margin="2dp"
29 android:scaleType="matrix"
30 android:src="@drawable/left_top" />
31
32 <com.ljp.ani.MyImageView
33 android:id="@+id/c_idea"
34 android:layout_width="wrap_content"
35 android:layout_height="wrap_content"
36 android:layout_margin="2dp"
37 android:scaleType="matrix"
38 android:src="@drawable/left_bottom" />
39 </LinearLayout>
40
41 <com.ljp.ani.MyImageView
42 android:id="@+id/c_constellation"
43 android:layout_width="wrap_content"
44 android:layout_height="wrap_content"
45 android:layout_margin="2dp"
46 android:scaleType="matrix"
47 android:src="@drawable/right" />
48 </LinearLayout>
49
50 <com.ljp.ani.MyImageView
51 android:id="@+id/c_recommend"
52 android:layout_width="wrap_content"
53 android:layout_height="wrap_content"
54 android:layout_margin="2dp"
55 android:scaleType="matrix"
56 android:src="@drawable/bottom" />
57 </LinearLayout>
58
59 </LinearLayout>
1 package com.ljp.ani;
2
3 import android.content.Context;
4 import android.graphics.Camera;
5 import android.graphics.Canvas;
6 import android.graphics.Matrix;
7 import android.graphics.Paint;
8 import android.graphics.PaintFlagsDrawFilter;
9 import android.graphics.drawable.BitmapDrawable;
10 import android.graphics.drawable.Drawable;
11 import android.os.Handler;
12 import android.os.Message;
13 import android.util.AttributeSet;
14 import android.view.MotionEvent;
15 import android.widget.ImageView;
16
17 public class MyImageView extends ImageView {
18
19 private boolean onAnimation = true;
20 private int rotateDegree = 10;
22 private boolean isFirst = true;
23 private float minScale = 0.95f;
24 private int vWidth;
25 private int vHeight;
26 private boolean isFinish = true, isActionMove = false, isScale = false;
27 private Camera camera;
28
29 boolean XbigY = false;
30 float RolateX = 0;
31 float RolateY = 0;
32
33 OnViewClick onclick = null;
34
35 public MyImageView(Context context) {
36 super(context);
37 // TODO Auto-generated constructor stub
38 camera = new Camera();
39 }
40
41 public MyImageView(Context context, AttributeSet attrs) {
42 super(context, attrs);
43 // TODO Auto-generated constructor stub
44 camera = new Camera();
45 }
46
47 public void SetAnimationOnOff(boolean oo) {
48 onAnimation = oo;
49 }
50
51 public void setOnClickIntent(OnViewClick onclick) {
52 this.onclick = onclick;
53 }
54
55 @Override
56 protected void onDraw(Canvas canvas) {
57 super.onDraw(canvas);
58 if (isFirst) {
59 isFirst = false;
60 init();
61 }
62 canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG
63 | Paint.FILTER_BITMAP_FLAG));
64 }
65
66 public void init() {
67 vWidth = getWidth() - getPaddingLeft() - getPaddingRight();
68 vHeight = getHeight() - getPaddingTop() - getPaddingBottom();
69 Drawable drawable = getDrawable();
70 BitmapDrawable bd = (BitmapDrawable) drawable;
71 bd.setAntiAlias(true);
72 }
73
74 @Override
75 public boolean onTouchEvent(MotionEvent event) {
76 super.onTouchEvent(event);
77 if (!onAnimation)
78 return true;
79
80 switch (event.getAction() & MotionEvent.ACTION_MASK) {
81 case MotionEvent.ACTION_DOWN:
82 float X = event.getX();
83 float Y = event.getY();
84 RolateX = vWidth / 2 - X;
85 RolateY = vHeight / 2 - Y;
86 XbigY = Math.abs(RolateX) > Math.abs(RolateY) ? true : false;
87
88 isScale = X > vWidth / 3 && X < vWidth * 2 / 3 && Y > vHeight / 3
89 && Y < vHeight * 2 / 3;
90 isActionMove = false;
91
92 if (isScale) {
93 handler.sendEmptyMessage(1);
94 } else {
95 rolateHandler.sendEmptyMessage(1);
96 }
97 break;
98 case MotionEvent.ACTION_MOVE:
99 float x = event.getX();
100 float y = event.getY();
101 if (x > vWidth || y > vHeight || x < 0 || y < 0) {
102 isActionMove = true;
103 } else {
104 isActionMove = false;
105 }
107 break;
108 case MotionEvent.ACTION_UP:
109 if (isScale) {
110 handler.sendEmptyMessage(6);
111 } else {
112 rolateHandler.sendEmptyMessage(6);
113 }
114 break;
115 }
116 return true;
117 }
118
119 public interface OnViewClick {
120 public void onClick();
121 }
122
123 private Handler rolateHandler = new Handler() {
124 private Matrix matrix = new Matrix();
125 private float count = 0;
126
127 @Override
128 public void handleMessage(Message msg) {
129 super.handleMessage(msg);
130 matrix.set(getImageMatrix());
131 switch (msg.what) {
132 case 1:
133 count = 0;
134 BeginRolate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));
135 rolateHandler.sendEmptyMessage(2);
136 break;
137 case 2:
138 BeginRolate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));
139 if (count < getDegree()) {
140 rolateHandler.sendEmptyMessage(2);
141 } else {
142 isFinish = true;
143 }
144 count++;
145 count++;
146 break;
147 case 3:
148 BeginRolate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));
149 if (count > 0) {
150 rolateHandler.sendEmptyMessage(3);
151 } else {
152 isFinish = true;
153 if (!isActionMove && onclick != null) {
154 onclick.onClick();
155 }
156 }
157 count--;
158 count--;
159 break;
160 case 6:
161 count = getDegree();
162 BeginRolate(matrix, (XbigY ? count : 0), (XbigY ? 0 : count));
163 rolateHandler.sendEmptyMessage(3);
164 break;
165 }
166 }
167 };
168
169 private synchronized void BeginRolate(Matrix matrix, float rolateX,
170 float rolateY) {
171 // Bitmap bm = getImageBitmap();
172 int scaleX = (int) (vWidth * 0.5f);
173 int scaleY = (int) (vHeight * 0.5f);
174 camera.save();
175 camera.rotateX(RolateY > 0 ? rolateY : -rolateY);
176 camera.rotateY(RolateX < 0 ? rolateX : -rolateX);
177 camera.getMatrix(matrix);
178 camera.restore();
179 // 控制中心点
180 if (RolateX > 0 && rolateX != 0) {
181 matrix.preTranslate(-vWidth, -scaleY);
182 matrix.postTranslate(vWidth, scaleY);
183 } else if (RolateY > 0 && rolateY != 0) {
184 matrix.preTranslate(-scaleX, -vHeight);
185 matrix.postTranslate(scaleX, vHeight);
186 } else if (RolateX < 0 && rolateX != 0) {
187 matrix.preTranslate(-0, -scaleY);
188 matrix.postTranslate(0, scaleY);
189 } else if (RolateY < 0 && rolateY != 0) {
190 matrix.preTranslate(-scaleX, -0);
191 matrix.postTranslate(scaleX, 0);
192 }
193 setImageMatrix(matrix);
194 }
195
196 private Handler handler = new Handler() {
197 private Matrix matrix = new Matrix();
198 private float s;
199 int count = 0;
200
201 @Override
202 public void handleMessage(Message msg) {
203 super.handleMessage(msg);
204 matrix.set(getImageMatrix());
205 switch (msg.what) {
206 case 1:
207 if (!isFinish) {
208 return;
209 } else {
210 isFinish = false;
211 count = 0;
212 s = (float) Math.sqrt(Math.sqrt(minScale));
213 BeginScale(matrix, s);
214 handler.sendEmptyMessage(2);
215 }
216 break;
217 case 2:
218 BeginScale(matrix, s);
219 if (count < 4) {
220 handler.sendEmptyMessage(2);
221 } else {
222 isFinish = true;
223 if (!isActionMove && onclick != null) {
224 onclick.onClick();
225 }
226 }
227 count++;
228 break;
229 case 6:
230 if (!isFinish) {
231 handler.sendEmptyMessage(6);
232 } else {
233 isFinish = false;
234 count = 0;
235 s = (float) Math.sqrt(Math.sqrt(1.0f / minScale));
236 BeginScale(matrix, s);
237 handler.sendEmptyMessage(2);
238 }
239 break;
240 }
241 }
242 };
243
244 private synchronized void BeginScale(Matrix matrix, float scale) {
245 int scaleX = (int) (vWidth * 0.5f);
246 int scaleY = (int) (vHeight * 0.5f);
247 matrix.postScale(scale, scale, scaleX, scaleY);
248 setImageMatrix(matrix);
249 }
250
251 public int getDegree() {
252 return rotateDegree;
253 }
254
255 public void setDegree(int degree) {
256 rotateDegree = degree;
257 }
258
259 public float getScale() {
260 return minScale;
261 }
262
263 public void setScale(float scale) {
264 minScale = scale;
265 }
266 }
1 import android.app.Activity;
2 import android.os.Bundle;
3 import android.widget.Toast;
4
5 public class TestRolateAnimActivity extends Activity {
7 MyImageView joke;
8
9 @Override
10 public void onCreate(Bundle savedInstanceState) {
11 super.onCreate(savedInstanceState);
12 setContentView(R.layout.main);
13
14 joke = (MyImageView) findViewById(R.id.c_joke);
15 joke.setOnClickIntent(new MyImageView.OnViewClick() {
17 @Override
18 public void onClick() {
19 Toast.makeText(TestRolateAnimActivity.this, "事件触发", 1000)
20 .show();
21 System.out.println("1");
22 }
23 });
24 }
25 }