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 }