首页 > 系统 > Android > 正文

Android动画之3D翻转效果实现函数分析

2019-10-24 21:06:53
字体:
来源:转载
供稿:网友
Android中的翻转动画效果的实现,Android中并没有提供直接做3D翻转的动画,所以关于3D翻转的动画效果需要我们自己实现,那么我们首先来分析一下Animation 和 Transformation,感兴趣的朋友可以了解下啊
 

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

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

复制代码代码如下:

package com.example.textviewtest; 
import android.graphics.Camera; 
import android.graphics.Matrix; 
import android.view.animation.Animation; 
import android.view.animation.Transformation; 
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; 
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(); 

// 生成Transformation 
@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.save(); 
if (mReverse) { 
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime); 
} else { 
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime)); 

camera.rotateY(degrees); 
// 取得变换后的矩阵 
camera.getMatrix(matrix); 
camera.restore(); 
matrix.preTranslate(-centerX, -centerY); 
matrix.postTranslate(centerX, centerY); 


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

下面是布局文件main.xml
复制代码代码如下:

View Code 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:background="@drawable/main_screen_bg" 
android:gravity="center_horizontal" 
android:orientation="vertical" 
tools:context=".MainActivity" > 
<Button 
android:id="@+id/next_btn" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:layout_marginTop="20dip" 
android:drawableTop="@drawable/qiangpiao_dropdown" 
android:text="下一个" /> 
<TextView 
android:id="@+id/tv" 
android:layout_width="300dip" 
android:layout_height="300dip" 
android:layout_gravity="center" 
android:background="@drawable/call_show_frame_safe" 
android:gravity="center" 
android:textColor="#ffffff" 
android:textSize="15sp" /> 
</LinearLayout> 

MainActivity的代码如下: 
复制代码代码如下:

View Code 
package com.example.textviewtest; 
import android.app.Activity; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.View; 
import android.view.animation.AccelerateInterpolator; 
import android.view.animation.Animation; 
import android.view.animation.DecelerateInterpolator; 
import android.widget.Button; 
import android.widget.TextView; 
public class MainActivity extends Activity { 
private TextView tv; 
private Button btn; 
private int count = 1; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.activity_main); 
tv = (TextView) findViewById(R.id.tv); 
tv.setText(String.valueOf(count)); 
btn = (Button) findViewById(R.id.next_btn); 
applyRotation(0, 90); 
btn.setOnClickListener(new View.OnClickListener() { 
@Override 
public void onClick(View v) { 
applyRotation(0, 90); 

}); 

private void applyRotation(float start, float end) { 
// 计算中心点 
final float centerX = tv.getWidth() / 2.0f; 
final float centerY = tv.getHeight() / 2.0f; 
final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end, 
centerX, centerY, 310.0f, true); 
rotation.setDuration(500); 
rotation.setFillAfter(true); 
rotation.setInterpolator(new AccelerateInterpolator()); 
// 设置监听 
rotation.setAnimationListener(new DisplayNextView()); 
tv.startAnimation(rotation); 

private final class DisplayNextView implements Animation.AnimationListener { 
public void onAnimationStart(Animation animation) { 

// 动画结束 
public void onAnimationEnd(Animation animation) { 
tv.post(new SwapViews()); 

public void onAnimationRepeat(Animation animation) { 


private final class SwapViews implements Runnable { 
public void run() { 
final float centerX = tv.getWidth() / 2.0f; 
final float centerY = tv.getHeight() / 2.0f; 
Rotate3dAnimation rotation = null; 
tv.requestFocus(); 
rotation = new Rotate3dAnimation(90, 0, centerX, centerY, 310.0f, 
false); 
rotation.setDuration(500); 
rotation.setFillAfter(true); 
rotation.setInterpolator(new DecelerateInterpolator()); 
// 开始动画 
tv.startAnimation(rotation); 
tv.setText(String.valueOf(count++)); 


@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
getMenuInflater().inflate(R.menu.activity_main, menu); 
return true; 


看懂了吗?呵呵。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表