Android动画分析之3D翻转效果

Android中的翻转动画效果的实现,首先看一下运行效果如上图所示.

Android中并没有提供直接做3D翻转的动画,所以关于3D翻转的动画效果需要我们自己实现,那么我们首先来分析一下Animation 和 Transformation。

Animation动画的主要接口,其中主要定义了动画的一些属性比如开始时间,持续时间,是否重复播放等等。而Transformation中则包含一个矩阵和alpha值,矩阵是用来做平移,旋转和缩放动画的,而alpha值是用来做alpha动画的,要实现3D旋转动画我们需要继承自Animation类来实现,我们需要重载getTransformation和applyTransformation,在getTransformation中Animation会根据动画的属性来产生一系列的差值点,然后将这些差值点传给applyTransformation,这个函数将根据这些点来生成不同的Transformation。下面是具体实现:

View Code
复制代码
 1 package com.example.textviewtest;
 2 
 3 import android.graphics.Camera;
 4 import android.graphics.Matrix;
 5 import android.view.animation.Animation;
 6 import android.view.animation.Transformation;
 7 
 8 public class Rotate3dAnimation extends Animation {
 9     // 开始角度
10     private final float mFromDegrees;
11     // 结束角度
12     private final float mToDegrees;
13     // 中心点
14     private final float mCenterX;
15     private final float mCenterY;
16     private final float mDepthZ;
17     // 是否需要扭曲
18     private final boolean mReverse;
19     // 摄像头
20     private Camera mCamera;
21 
22     public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX,
23             float centerY, float depthZ, boolean reverse) {
24         mFromDegrees = fromDegrees;
25         mToDegrees = toDegrees;
26         mCenterX = centerX;
27         mCenterY = centerY;
28         mDepthZ = depthZ;
29         mReverse = reverse;
30     }
31 
32     @Override
33     public void initialize(int width, int height, int parentWidth,
34             int parentHeight) {
35         super.initialize(width, height, parentWidth, parentHeight);
36         mCamera = new Camera();
37     }
38 
39     // 生成Transformation
40     @Override
41     protected void applyTransformation(float interpolatedTime, Transformation t) {
42         final float fromDegrees = mFromDegrees;
43         // 生成中间角度
44         float degrees = fromDegrees
45                 + ((mToDegrees - fromDegrees) * interpolatedTime);
46 
47         final float centerX = mCenterX;
48         final float centerY = mCenterY;
49         final Camera camera = mCamera;
50 
51         final Matrix matrix = t.getMatrix();
52 
53         camera.save();
54         if (mReverse) {
55             camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
56         } else {
57             camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
58         }
59         camera.rotateY(degrees);
60         // 取得变换后的矩阵
61         camera.getMatrix(matrix);
62         camera.restore();
63 
64         matrix.preTranslate(-centerX, -centerY);
65         matrix.postTranslate(centerX, centerY);
66     }
67 }
复制代码

其中包括了旋转的开始和结束角度,中心点、是否扭曲、和一个Camera,这里我们主要分析applyTransformation函数,其中第一个参数就是通过getTransformation函数传递的差指点,然后我们根据这个差值通过线性差值算法计算出一个中间角度degrees,Camera类是用来实现绕Y轴旋转后透视投影的,因此我们首先通过t.getMatrix()取得当前的矩阵,然后通过camera.translate来对矩阵进行平移变换操作,camera.rotateY进行旋转。这样我们就可以很轻松的实现3D旋转效果了。

下面是布局文件main.xml:

View Code
复制代码
 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:background="@drawable/main_screen_bg"
 6     android:gravity="center_horizontal"
 7     android:orientation="vertical"
 8     tools:context=".MainActivity" >
 9 
10     <Button
11         android:id="@+id/next_btn"
12         android:layout_width="wrap_content"
13         android:layout_height="wrap_content"
14         android:layout_marginTop="20dip"
15         android:drawableTop="@drawable/qiangpiao_dropdown"
16         android:text="下一个" />
17 
18     <TextView
19         android:id="@+id/tv"
20         android:layout_width="300dip"
21         android:layout_height="300dip"
22         android:layout_gravity="center"
23         android:background="@drawable/call_show_frame_safe"
24         android:gravity="center"
25         android:textColor="#ffffff"
26         android:textSize="15sp" />
27 
28 </LinearLayout>
复制代码

MainActivity的代码如下:

View Code
复制代码
 1 package com.example.textviewtest;
 2 
 3 import android.app.Activity;
 4 import android.os.Bundle;
 5 import android.view.Menu;
 6 import android.view.View;
 7 import android.view.animation.AccelerateInterpolator;
 8 import android.view.animation.Animation;
 9 import android.view.animation.DecelerateInterpolator;
10 import android.widget.Button;
11 import android.widget.TextView;
12 
13 public class MainActivity extends Activity {
14     private TextView tv;
15     private Button btn;
16     private int count = 1;
17 
18     @Override
19     protected void onCreate(Bundle savedInstanceState) {
20         super.onCreate(savedInstanceState);
21         setContentView(R.layout.activity_main);
22         tv = (TextView) findViewById(R.id.tv);
23         tv.setText(String.valueOf(count));
24         btn = (Button) findViewById(R.id.next_btn);
25         applyRotation(0, 90);
26 
27         btn.setOnClickListener(new View.OnClickListener() {
28 
29             @Override
30             public void onClick(View v) {
31                 applyRotation(0, 90);
32             }
33         });
34 
35     }
36 
37     private void applyRotation(float start, float end) {
38         // 计算中心点
39         final float centerX = tv.getWidth() / 2.0f;
40         final float centerY = tv.getHeight() / 2.0f;
41 
42         final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end,
43                 centerX, centerY, 310.0f, true);
44         rotation.setDuration(500);
45         rotation.setFillAfter(true);
46         rotation.setInterpolator(new AccelerateInterpolator());
47         // 设置监听
48         rotation.setAnimationListener(new DisplayNextView());
49 
50         tv.startAnimation(rotation);
51     }
52 
53     private final class DisplayNextView implements Animation.AnimationListener {
54 
55         public void onAnimationStart(Animation animation) {
56         }
57 
58         // 动画结束
59         public void onAnimationEnd(Animation animation) {
60             tv.post(new SwapViews());
61         }
62 
63         public void onAnimationRepeat(Animation animation) {
64         }
65     }
66 
67     private final class SwapViews implements Runnable {
68 
69         public void run() {
70             final float centerX = tv.getWidth() / 2.0f;
71             final float centerY = tv.getHeight() / 2.0f;
72             Rotate3dAnimation rotation = null;
73 
74             tv.requestFocus();
75 
76             rotation = new Rotate3dAnimation(90, 0, centerX, centerY, 310.0f,
77                     false);
78             rotation.setDuration(500);
79             rotation.setFillAfter(true);
80             rotation.setInterpolator(new DecelerateInterpolator());
81             // 开始动画
82             tv.startAnimation(rotation);
83             tv.setText(String.valueOf(count++));
84         }
85     }
86 
87     @Override
88     public boolean onCreateOptionsMenu(Menu menu) {
89         getMenuInflater().inflate(R.menu.activity_main, menu);
90         return true;
91     }
92 
93 }
复制代码

看懂了吗?呵呵。

囧神的世界你不懂,虫哥的生活你没有,只有程序猿的世界大家才知道。程序猿们,为了自己的精彩世界奋斗吧,努力吧!加油……
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值