代码改变世界

Android系列之浅谈Android 3D旋转

2010-07-28 14:36  $等待$  阅读(11008)  评论(77编辑  收藏  举报

最近和一哥们在聊Android的3D旋转效果的技术实现的事情,今天正好有点时间就把技术细节写了出来

在ANDROID中实现3D旋转直接使用animation配合camera就可以实现,在apidemo里就有这样的实例

我们首先做一个继承animation的类Rotate3d.java

 

1 public class Rotate3d extends Animation {
2 private float mFromDegree;
3 private float mToDegree;
4 private float mCenterX;
5 private float mCenterY;
6 private float mLeft;
7 private float mTop;
8 private Camera mCamera;
9 private static final String TAG = "Rotate3d";
10
11 public Rotate3d(float fromDegree, float toDegree, float left, float top,
12 float centerX, float centerY) {
13 this.mFromDegree = fromDegree;
14 this.mToDegree = toDegree;
15 this.mLeft = left;
16 this.mTop = top;
17 this.mCenterX = centerX;
18 this.mCenterY = centerY;
19
20 }
21
22 @Override
23 public void initialize(int width, int height, int parentWidth,
24 int parentHeight) {
25 super.initialize(width, height, parentWidth, parentHeight);
26 mCamera = new Camera();
27 }
28
29 @Override
30 protected void applyTransformation(float interpolatedTime, Transformation t) {
31 final float FromDegree = mFromDegree;
32 float degrees = FromDegree + (mToDegree - mFromDegree)
33 * interpolatedTime;
34 final float centerX = mCenterX;
35 final float centerY = mCenterY;
36 final Matrix matrix = t.getMatrix();
37
38 if (degrees <= -76.0f) {
39 degrees = -90.0f;
40 mCamera.save();
41 mCamera.rotateY(degrees);
42 mCamera.getMatrix(matrix);
43 mCamera.restore();
44 } else if(degrees >=76.0f){
45 degrees = 90.0f;
46 mCamera.save();
47 mCamera.rotateY(degrees);
48 mCamera.getMatrix(matrix);
49 mCamera.restore();
50 }else{
51 mCamera.save();
52 //这里很重要哦。
53   mCamera.translate(0, 0, centerX);
54 mCamera.rotateY(degrees);
55 mCamera.translate(0, 0, -centerX);
56 mCamera.getMatrix(matrix);
57 mCamera.restore();
58 }
59
60 matrix.preTranslate(-centerX, -centerY);
61 matrix.postTranslate(centerX, centerY);
62 }
63 }
64
65  public class Rotate3d extends Animation {
66 private float mFromDegree;
67 private float mToDegree;
68 private float mCenterX;
69 private float mCenterY;
70 private float mLeft;
71 private float mTop;
72 private Camera mCamera;
73 private static final String TAG = "Rotate3d";
74
75 public Rotate3d(float fromDegree, float toDegree, float left, float top,
76 float centerX, float centerY) {
77 this.mFromDegree = fromDegree;
78 this.mToDegree = toDegree;
79 this.mLeft = left;
80 this.mTop = top;
81 this.mCenterX = centerX;
82 this.mCenterY = centerY;
83
84 }
85
86 @Override
87 public void initialize(int width, int height, int parentWidth,
88 int parentHeight) {
89 super.initialize(width, height, parentWidth, parentHeight);
90 mCamera = new Camera();
91 }
92
93 @Override
94 protected void applyTransformation(float interpolatedTime, Transformation t) {
95 final float FromDegree = mFromDegree;
96 float degrees = FromDegree + (mToDegree - mFromDegree)
97 * interpolatedTime;
98 final float centerX = mCenterX;
99 final float centerY = mCenterY;
100 final Matrix matrix = t.getMatrix();
101
102 if (degrees <= -76.0f) {
103 degrees = -90.0f;
104 mCamera.save();
105 mCamera.rotateY(degrees);
106 mCamera.getMatrix(matrix);
107 mCamera.restore();
108 } else if(degrees >=76.0f){
109 degrees = 90.0f;
110 mCamera.save();
111 mCamera.rotateY(degrees);
112 mCamera.getMatrix(matrix);
113 mCamera.restore();
114 }else{
115 mCamera.save();
116 //这里很重要哦。
117   mCamera.translate(0, 0, centerX);
118 mCamera.rotateY(degrees);
119 mCamera.translate(0, 0, -centerX);
120 mCamera.getMatrix(matrix);
121 mCamera.restore();
122 }
123
124 matrix.preTranslate(-centerX, -centerY);
125 matrix.postTranslate(centerX, centerY);
126 }
127 }
128
129  

有了这个类一切都会变得简单的,接着只要在activity中写两个Rotate3d的对象,让两个view,分别做这两个对象的animation就好了;

 

1 //下面两句很关键哦,
2 Rotate3d leftAnimation = new Rotate3d(-0, -90, 0, 0, mCenterX, mCenterY);
3 Rotate3d rightAnimation = new Rotate3d(-0+90, -90+90, 0.0f, 0.0f, mCenterX, mCenterY);
4
5 leftAnimation.setFillAfter(true);
6 leftAnimation.setDuration(1000);
7 rightAnimation.setFillAfter(true);
8 rightAnimation.setDuration(1000);
9
10 mImageView1.startAnimation(leftAnimation);
11 mImageView2.startAnimation(rightAnimation);
12

最后就是还要写一下mImageView1,mImageView2的xml,

 

1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:orientation="vertical"
4 android:layout_width="fill_parent"
5 android:layout_height="wrap_content"
6 >
7
8 <FrameLayout
9 android:layout_width="fill_parent"
10 android:layout_height="fill_parent">
11
12 <ImageView
13 android:id="@+id/image1"
14 android:layout_gravity="center_horizontal"
15 android:layout_width="fill_parent"
16 android:layout_height="wrap_content"
17 android:src="@drawable/image1"
18 />
19 <ImageView
20 android:id="@+id/image2"
21 android:background="#ffff0000"
22 android:layout_gravity="center_horizontal"
23 android:layout_width="fill_parent"
24 android:layout_height="wrap_content"
25 android:src="@drawable/image2"
26 />
27
28 </FrameLayout>
29 </LinearLayout>

 需要源代码的留下邮箱!