Android使用Rotate3dAnimation实现3D旋转动画效果的实例代码

时间:2021-10-15 20:57:07

利用Android的ApiDemos的Rotate3dAnimation实现了个图片3D旋转的动画,围绕Y轴进行旋转,还可以实现Z轴的缩放。点击开始按钮开始旋转,点击结束按钮停止旋转。

Android使用Rotate3dAnimation实现3D旋转动画效果的实例代码Android使用Rotate3dAnimation实现3D旋转动画效果的实例代码

代码如下::

Rotate3dAnimation.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
public class Rotate3dAnimation extends Animation {
 private final float mFromDegrees;
 private final float mToDegrees;
 private final float mCenterX;
 private final float mCenterY;
 private final float mDepthZ;
 private final boolean mReverse;
 private Camera mCamera;
 /**
 * Creates a new 3D rotation on the Y axis. The rotation is defined by its
 * start angle and its end angle. Both angles are in degrees. The rotation
 * is performed around a center point on the 2D space, definied by a pair
 * of X and Y coordinates, called centerX and centerY. When the animation
 * starts, a translation on the Z axis (depth) is performed. The length
 * of the translation can be specified, as well as whether the translation
 * should be reversed in time.
 *
 * @param fromDegrees the start angle of the 3D rotation
 * @param toDegrees the end angle of the 3D rotation
 * @param centerX the X center of the 3D rotation
 * @param centerY the Y center of the 3D rotation
 * @param reverse true if the translation should be reversed, false otherwise
 */
 public Rotate3dAnimation(float fromDegrees, float toDegrees,
 float centerX, float centerY, float depthZ, boolean reverse) {
 mFromDegrees = fromDegrees;
 mToDegrees = toDegrees;
 mCenterX = centerX;
 mCenterY = centerY;
 mDepthZ = depthZ;
 mReverse = reverse;
 }
 @Override
 public void initialize(int width, int height, int parentWidth, int parentHeight) {
 super.initialize(width, height, parentWidth, parentHeight);
 mCamera = new Camera();
 }
 @Override
 protected void applyTransformation(float interpolatedTime, Transformation t) {
 final float fromDegrees = mFromDegrees;
 float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);
 final float centerX = mCenterX;
 final float centerY = mCenterY;
 final Camera camera = mCamera;
 final Matrix matrix = t.getMatrix();
 //保存一次camera初始状态,用于restore()
 camera.save();
 if (mReverse) {
 camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
 } else {
 camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
 }
 //围绕Y轴旋转degrees度
 camera.rotateY(degrees);
 //行camera中取出矩阵,赋值给matrix
 camera.getMatrix(matrix);
 //camera恢复到初始状态,继续用于下次的计算
 camera.restore();
 matrix.preTranslate(-centerX, -centerY);
 matrix.postTranslate(centerX, centerY);
 }
}

Test3DRotateActivity.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
public class Test3DRotateActivity extends Activity {
 /** Called when the activity is first created. */
 private final String TAG="Test3DRotateActivity";
 private ImageView image;
 private Button start ,stop;
 private Rotate3dAnimation rotation;
 private StartNextRotate startNext;
 @Override
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main);
 image = (ImageView) findViewById(R.id.image);
 start=(Button) findViewById(R.id.start);
 stop = (Button) findViewById(R.id.stop);
 start.setOnClickListener(new OnClickListener() {
 public void onClick(View v) {
 // TODO Auto-generated method stub
 //进行360度的旋转
 startRotation(0,360);
 }
 });
 stop.setOnClickListener(new OnClickListener() {
 public void onClick(View v) {
 // TODO Auto-generated method stub
 image.clearAnimation();
 }
 });
 }
 private void startRotation(float start, float end) {
 // 计算中心点
 final float centerX = image.getWidth() / 2.0f;
 final float centerY = image.getHeight() / 2.0f;
 Log.d(TAG, "centerX="+centerX+", centerY="+centerY);
 // Create a new 3D rotation with the supplied parameter
 // The animation listener is used to trigger the next animation
 //final Rotate3dAnimation rotation =new Rotate3dAnimation(start, end, centerX, centerY, 310.0f, true);
 //Z轴的缩放为0
 rotation =new Rotate3dAnimation(start, end, centerX, centerY, 0f, true);
 rotation.setDuration(2000);
 rotation.setFillAfter(true);
 //rotation.setInterpolator(new AccelerateInterpolator());
 //匀速旋转
 rotation.setInterpolator(new LinearInterpolator());
 //设置监听
 startNext = new StartNextRotate();
 rotation.setAnimationListener(startNext);
 image.startAnimation(rotation);
 }
 private class StartNextRotate implements AnimationListener{
 public void onAnimationEnd(Animation animation) {
 // TODO Auto-generated method stub
 Log.d(TAG, "onAnimationEnd......");
 image.startAnimation(rotation);
 }
 public void onAnimationRepeat(Animation animation) {
 // TODO Auto-generated method stub
 }
 public void onAnimationStart(Animation animation) {
 // TODO Auto-generated method stub
 }
 }
}

main.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:orientation="vertical" >
 <Button
 android:id="@+id/start"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="开始" />
 <Button
 android:id="@+id/stop"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="结束" />
 <ImageView
 android:id="@+id/image"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:src="@drawable/t1"
 />
</LinearLayout>

代码中用Camera来实现动画,Camera就是一个摄像机,一个物体原地不动,我们带着摄像机按设定的角度进行移动,之后从Camera中取出完成该动画的Matrix,然后画我们的物体,这个就是这个3D动画实现的原理。
具体的解释见代码中注释部分,重点说一下Rotate3dAnimation.java中的

?
1
2
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);

由于旋转是以(0,0)为中心的,所以为了把界面的中心与(0,0)对齐,就要preTranslate(-centerX, -centerY),旋转完成后,调用postTranslate(centerX, centerY),再把图片移回来,这样看到的动画效果就是activity的界面图片从在centerX为中心绕Y轴旋转了。
你还可以把上面代码改成

?
1
2
matrix.preTranslate(-centerX, 0);
matrix.postTranslate(centerX, 0);

看有什么不同效果。

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。

原文链接:https://blog.csdn.net/heqiangflytosky/article/details/17042977