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

http://blog.csdn.net/sunboy_2050/article/details/7483166

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

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

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

1、Rotate3D(Animation)

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

[java] view
plain
copyprint?

  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(0, 0, centerX);       // 位移x  
  45.             mCamera.rotateY(degrees);  
  46.             mCamera.translate(0, 0, -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
copyprint?

  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(90, 0, mCenterX, mCenterY);     // 下一页的【question2】旋转方向(从90度转到0,参考系为水平方向为0度)(起始第一题)  
  15.     lQuest2Animation.setFillAfter(true);  
  16.     lQuest2Animation.setDuration(duration);  
  17.   
  18.     rQuest1Animation = new Rotate3D(0, 90, mCenterX, mCenterY);     // 上一页的【question1】旋转方向(从0度转到90,参考系为水平方向为0度)  
  19.     rQuest1Animation.setFillAfter(true);  
  20.     rQuest1Animation.setDuration(duration);  
  21.   
  22.     rQuest2Animation = new Rotate3D(-90, 0, mCenterX, mCenterY);    // 上一页的【question2】旋转方向(从-90度转到0,参考系为水平方向为0度)  
  23.     rQuest2Animation.setFillAfter(true);  
  24.     rQuest2Animation.setDuration(duration);  
  25. }  

2、Activity

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

main.xml

[html] view
plain
copyprint?

  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
copyprint?

  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
copyprint?

  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
copyprint?

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

源码下载

参考推荐:

animation

时间: 2024-09-11 08:05:48

Android 滑动效果进阶篇(五)—— 3D旋转的相关文章

Android滑动效果进阶篇(六) 倒影效果

上篇介绍了使用Animation实现3D动画旋转翻页效果,现在介绍图片倒影实现,先看效果图 本示例主要通过自定义Gallery和ImageAdapter(继承自BaseAdapter)实现 1.倒影绘制 ImageAdapter继承自 BaseAdapter,详细实现可见 Android 滑动效果入门篇(二)-- Gallery 这里重点介绍倒影原理及实现 倒影原理: 倒影效果是主要由原图+间距+倒影三部分组成,高度大约为原图的3/2(原图为1.倒影为1/2) 原图,就是我们 看到了最开始的图片

Android 滑动效果进阶篇(六)—— 倒影效果

http://blog.csdn.net/sunboy_2050/article/details/7483169 上篇介绍了使用Animation实现3D动画旋转翻页效果,现在介绍图片倒影实现,先看效果图 本示例主要通过自定义Gallery和ImageAdapter(继承自BaseAdapter)实现 1.倒影绘制 ImageAdapter继承自BaseAdapter,详细实现可见 Android 滑动效果入门篇(二)-- Gallery 这里重点介绍倒影原理及实现 倒影原理: 倒影效果是主要由

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

前面介绍了利用Android自带的控件,进行滑动翻页制作效果,现在我们通过代码实现一些滑动翻页的动画效果. Animation实现动画有两个方式:帧动画(frame-by-frame animation)和补间动画(tweened animation) 本示 例通过继承Animation自定义Rotate3D,实现3D翻页效果.效果图如下: 1.Rotate3D(Animation) 首先,自定义Animation的3D动画类Rotate3D public class Rotate3D exte

Android 滑动效果基础篇(三)—— Gallery仿图像集浏览

Android系统自带一个Gallery浏览图片的应用,通过手指拖动时能够非常流畅的显示图片,用户交互和体验都很好. 本示例就是通过Gallery和自定义的View,模仿实现一个仿Gallery图像集的图片浏览效果.效果图如下: 1.基本原理 在 Activity 中实现 OnGestureListener 的接口 onFling() 手势事件,通过自定义的 View 绘制draw() 图片 2.Activity Activity中,通过onTouchEvent() 注册 myGesture.o

Android滑动效果入门篇(二) Gallery

Gallery 是Android官方提供的一个View容器类,继承于AbsSpinner类,用于实现页面滑动效果. 从上面的继承关系可 以看出,AbsSpinner类继承自AdapterView,因此我们可以自定义实现Adapter,来填充Gallery容器的数据. 本示 例通过自己实现一个Adapter,来填充Gallery容器的图片数据,首先看效果: Activity import android.app.Activity; import android.os.Bundle; import

Android滑动效果基础篇(三) Gallery仿图像集浏览

Android系统自带一个Gallery浏览图片的应用,通过手指拖动时能够非常流畅的显示图片,用户交互和体验都很好. 本示例就是通过Gallery和自定义的View,模仿实现一个仿Gallery图像集的图片浏览效果.效果图如下: 1.基本原理 在 Activity 中实现 OnGestureListener 的接口 onFling() 手势事件,通过自定义的 View 绘制draw() 图片 2. Activity Activity中,通过onTouchEvent() 注册 myGesture.

Android 滑动效果入门篇(二)—— Gallery

http://blog.csdn.net/sunboy_2050/article/details/7442556 Gallery 是Android官方提供的一个View容器类,继承于AbsSpinner类,用于实现页面滑动效果. 从上面的继承关系可以看出,AbsSpinner类继承自AdapterView,因此我们可以自定义实现Adapter,来填充Gallery容器的数据. 本示例通过自己实现一个Adapter,来填充Gallery容器的图片数据,首先看效果: Activity [java] 

Android滑动效果入门篇(一) ViewFlipper

ViewFilpper 是Android官方提供的一个View容器类,继承于ViewAnimator类,用于实现页面切换,也可以设定时间间隔,让 它自动播放. 又ViewAnimator继承至于FrameLayout的,所以ViewFilpper的Layout里面可以放置多个View,继承关系如下: 本示例 通过ViewFlipper和GestureDetector.OnGestureListener实现自动播放和手势滑屏事件,先看效果: Activity import android.app.

Android 滑动效果基础篇(四)—— Gallery + GridView

http://blog.csdn.net/sunboy_2050/article/details/7467739 Android系统自带一个GridView和Gallery两个控件,GridView网格显示,Gallery单个浏览,两者结合起来可以真正实现Gallery浏览图片效果. 本示例通过GridView和Gallery两个控件,模仿实现一个完整的仿Gallery图像集的图片浏览效果.效果图如下: 1.GridView 首先,自定义一个GridImageAdapter图片适配器,用于填充G