Android 滑动效果进阶篇(五)—— 3D旋转

前面介绍了利用Android自带的控件,进行滑动翻页制作效果,现在我们通过代码实现一些滑动翻页的动画效果。

Animation实现动画有两个方式:帧动画(frame-by-frame animation)和补间动画(tweened animation


本示例通过继承Animation自定义Rotate3D,实现3D翻页效果。效果图如下:

Android 滑动效果进阶篇(五)—— 3D旋转_第1张图片


1、Rotate3D(Animation)

首先,自定义Animation的3D动画类Rotate3D

[java] view plain copy print ?
  1. public class Rotate3D extends Animation {  
  2.     private float fromDegree;   // 旋转起始角度  
  3.     private float toDegree;     // 旋转终止角度  
  4.     private float mCenterX;     // 旋转中心x  
  5.     private float mCenterY;     // 旋转中心y  
  6.     private Camera mCamera;  
  7.   
  8.     public Rotate3D(float fromDegree, float toDegree, float centerX, float centerY) {  
  9.         this.fromDegree = fromDegree;  
  10.         this.toDegree = toDegree;  
  11.         this.mCenterX = centerX;  
  12.         this.mCenterY = centerY;  
  13.   
  14.     }  
  15.   
  16.     @Override  
  17.     public void initialize(int width, int height, int parentWidth, int parentHeight) {  
  18.         super.initialize(width, height, parentWidth, parentHeight);  
  19.         mCamera = new Camera();  
  20.     }  
  21.   
  22.     @Override  
  23.     protected void applyTransformation(float interpolatedTime, Transformation t) {  
  24.         final float FromDegree = fromDegree;  
  25.         float degrees = FromDegree + (toDegree - fromDegree) * interpolatedTime;    // 旋转角度(angle)  
  26.         final float centerX = mCenterX;  
  27.         final float centerY = mCenterY;  
  28.         final Matrix matrix = t.getMatrix();  
  29.   
  30.         if (degrees <= -76.0f) {  
  31.             degrees = -90.0f;  
  32.             mCamera.save();  
  33.             mCamera.rotateY(degrees);       // 旋转  
  34.             mCamera.getMatrix(matrix);  
  35.             mCamera.restore();  
  36.         } else if (degrees >= 76.0f) {  
  37.             degrees = 90.0f;  
  38.             mCamera.save();  
  39.             mCamera.rotateY(degrees);  
  40.             mCamera.getMatrix(matrix);  
  41.             mCamera.restore();  
  42.         } else {  
  43.             mCamera.save();  
  44.             mCamera.translate(00, centerX);       // 位移x  
  45.             mCamera.rotateY(degrees);  
  46.             mCamera.translate(00, -centerX);  
  47.             mCamera.getMatrix(matrix);  
  48.             mCamera.restore();  
  49.         }  
  50.   
  51.         matrix.preTranslate(-centerX, -centerY);  
  52.         matrix.postTranslate(centerX, centerY);  
  53.     }  
  54. }  

然后,实例化Rotate3D的旋转方向

[java] view plain copy print ?
  1. public void initAnimation() {  
  2.     // 获取旋转中心  
  3.     DisplayMetrics dm = new DisplayMetrics();  
  4.     dm = getResources().getDisplayMetrics();  
  5.     mCenterX = dm.widthPixels / 2;  
  6.     mCenterY = dm.heightPixels / 2;  
  7.       
  8.     // 定义旋转方向  
  9.     int duration = 1000;  
  10.     lQuest1Animation = new Rotate3D(0, -90, mCenterX, mCenterY);    // 下一页的【question1】旋转方向(从0度转到-90,参考系为水平方向为0度)  
  11.     lQuest1Animation.setFillAfter(true);  
  12.     lQuest1Animation.setDuration(duration);  
  13.   
  14.     lQuest2Animation = new Rotate3D(900, mCenterX, mCenterY);     // 下一页的【question2】旋转方向(从90度转到0,参考系为水平方向为0度)(起始第一题)  
  15.     lQuest2Animation.setFillAfter(true);  
  16.     lQuest2Animation.setDuration(duration);  
  17.   
  18.     rQuest1Animation = new Rotate3D(090, mCenterX, mCenterY);     // 上一页的【question1】旋转方向(从0度转到90,参考系为水平方向为0度)  
  19.     rQuest1Animation.setFillAfter(true);  
  20.     rQuest1Animation.setDuration(duration);  
  21.   
  22.     rQuest2Animation = new Rotate3D(-900, mCenterX, mCenterY);    // 上一页的【question2】旋转方向(从-90度转到0,参考系为水平方向为0度)  
  23.     rQuest2Animation.setFillAfter(true);  
  24.     rQuest2Animation.setDuration(duration);  
  25. }  

2、Activity

首先,定义两个布局文件,用于旋转的画面切换

main.xml

[html] view plain copy print ?
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:id="@+id/layout_main"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="wrap_content"              
  5.     android:orientation="vertical">  
  6.   
  7. ...  
  8.   
  9. </LinearLayout>  

next.xml
[html] view plain copy print ?
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:id="@+id/layout_next"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="wrap_content"              
  5.     android:orientation="vertical">  
  6.   
  7. ...  
  8.   
  9. </LinearLayout>  
限于篇幅,完整布局文件请详见源码 ^_^


然后,初始化两个旋转的布局文件资源

[java] view plain copy print ?
  1. private void initMain(){  
  2.        setContentView(R.layout.main);  
  3.   
  4.     layoutmain = (LinearLayout)findViewById(R.id.layout_main);  
  5.     btn_MainLast = (Button)findViewById(R.id.main_last);  
  6.     btn_MainNext = (Button)findViewById(R.id.main_next);  
  7.       
  8.     btn_MainLast.setOnClickListener(listener);  
  9.     btn_MainNext.setOnClickListener(listener);  
  10. }  
  11.   
  12. private void initNext(){  
  13.        setContentView(R.layout.next);  
  14.   
  15.     layoutnext = (LinearLayout)findViewById(R.id.layout_next);  
  16.     btn_NextLast = (Button)findViewById(R.id.next_last);  
  17.     btn_NextNext = (Button)findViewById(R.id.next_next);  
  18.       
  19.     btn_NextLast.setOnClickListener(listener);  
  20.     btn_NextNext.setOnClickListener(listener);  
  21. }  

最后,设置布局文件中的按钮监听事件,响应3D旋转动画和方向
[java] view plain copy print ?
  1. private View.OnClickListener listener = new View.OnClickListener() {  
  2.     @Override  
  3.     public void onClick(View v) {  
  4.         switch (v.getId()) {  
  5.         case R.id.main_last:    // 上一页  
  6.             layoutmain.startAnimation(lQuest1Animation);    // 当前页向左旋转(0,-90)  
  7.             initNext();  
  8.             layoutnext.startAnimation(lQuest2Animation);    // 下一页向左旋转(90, 0)  
  9.             break;  
  10.         case R.id.main_next:    // 下一页  
  11.             layoutmain.startAnimation(rQuest1Animation);    // 当前页向右旋转(0,90)  
  12.             initNext();  
  13.             layoutnext.startAnimation(rQuest2Animation);    // 下一页向右旋转(-90, 0)  
  14.             break;  
  15.         case R.id.next_last:  
  16.             layoutnext.startAnimation(lQuest1Animation);  
  17.             initMain();  
  18.             layoutmain.startAnimation(lQuest2Animation);  
  19.             break;  
  20.         case R.id.next_next:  
  21.             layoutnext.startAnimation(rQuest1Animation);  
  22.             initMain();  
  23.             layoutmain.startAnimation(rQuest2Animation);  
  24.             break;  
  25.         }  
  26.     }  
  27. }; 

你可能感兴趣的:(java,android,layout,animation,button,Matrix)