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:
<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的代码如下:
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; } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:notice#nhooo.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。