zoukankan      html  css  js  c++  java
  • Android 滑动效果进阶篇(五)—— 3D旋转

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

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

     

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

     

    1、Rotate3D(Animation)

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

    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的旋转方向

    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

    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

    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>  

    限于篇幅,完整布局文件请详见源码 ^_^

     

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

    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旋转动画和方向

      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. }; 
  • 相关阅读:
    1.在html中引入js文件和Jquery框架
    在html页面添加一个隐藏域,并渲染一个需要保存的数值,在js中需要再获取,而不影响页面结构
    Django REST framework 使用简记
    BlockingQueue-线程的阻塞队列
    ExecutorService生命周期
    Java transient关键字使用小记
    数组
    Git 常用命令
    Git 常见报错
    python 常见报错
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/3585802.html
Copyright © 2011-2022 走看看