首页 > 系统 > Android > 正文

Android实现3D翻转动画效果

2019-10-22 18:18:11
字体:
来源:转载
供稿:网友

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VEVB武林网。


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表