最近和一哥们在聊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
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
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 >
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 >
需要源代码的留下邮箱!