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 }