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

时间:2021-07-08 15:15:41

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;
}
}


看懂了吗?呵呵。