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

1、Rotate3D(Animation)
首先,自定义Animation的3D动画类Rotate3D
- public class Rotate3D extends Animation {
- private float fromDegree; // 旋转起始角度
- private float toDegree; // 旋转终止角度
- private float mCenterX; // 旋转中心x
- private float mCenterY; // 旋转中心y
- private Camera mCamera;
- public Rotate3D(float fromDegree, float toDegree, float centerX, float centerY) {
- this.fromDegree = fromDegree;
- this.toDegree = toDegree;
- this.mCenterX = centerX;
- this.mCenterY = centerY;
- }
- @Override
- public void initialize(int width, int height, int parentWidth, int parentHeight) {
- super.initialize(width, height, parentWidth, parentHeight);
- mCamera = new Camera();
- }
- @Override
- protected void applyTransformation(float interpolatedTime, Transformation t) {
- final float FromDegree = fromDegree;
- float degrees = FromDegree + (toDegree - fromDegree) * interpolatedTime; // 旋转角度(angle)
- final float centerX = mCenterX;
- final float centerY = mCenterY;
- final Matrix matrix = t.getMatrix();
- if (degrees <= -76.0f) {
- degrees = -90.0f;
- mCamera.save();
- mCamera.rotateY(degrees); // 旋转
- mCamera.getMatrix(matrix);
- mCamera.restore();
- } else if (degrees >= 76.0f) {
- degrees = 90.0f;
- mCamera.save();
- mCamera.rotateY(degrees);
- mCamera.getMatrix(matrix);
- mCamera.restore();
- } else {
- mCamera.save();
- mCamera.translate(0, 0, centerX); // 位移x
- mCamera.rotateY(degrees);
- mCamera.translate(0, 0, -centerX);
- mCamera.getMatrix(matrix);
- mCamera.restore();
- }
- matrix.preTranslate(-centerX, -centerY);
- matrix.postTranslate(centerX, centerY);
- }
- }
然后,实例化Rotate3D的旋转方向
- public void initAnimation() {
- // 获取旋转中心
- DisplayMetrics dm = new DisplayMetrics();
- dm = getResources().getDisplayMetrics();
- mCenterX = dm.widthPixels / 2;
- mCenterY = dm.heightPixels / 2;
- // 定义旋转方向
- int duration = 1000;
- lQuest1Animation = new Rotate3D(0, -90, mCenterX, mCenterY); // 下一页的【question1】旋转方向(从0度转到-90,参考系为水平方向为0度)
- lQuest1Animation.setFillAfter(true);
- lQuest1Animation.setDuration(duration);
- lQuest2Animation = new Rotate3D(90, 0, mCenterX, mCenterY); // 下一页的【question2】旋转方向(从90度转到0,参考系为水平方向为0度)(起始第一题)
- lQuest2Animation.setFillAfter(true);
- lQuest2Animation.setDuration(duration);
- rQuest1Animation = new Rotate3D(0, 90, mCenterX, mCenterY); // 上一页的【question1】旋转方向(从0度转到90,参考系为水平方向为0度)
- rQuest1Animation.setFillAfter(true);
- rQuest1Animation.setDuration(duration);
- rQuest2Animation = new Rotate3D(-90, 0, mCenterX, mCenterY); // 上一页的【question2】旋转方向(从-90度转到0,参考系为水平方向为0度)
- rQuest2Animation.setFillAfter(true);
- rQuest2Animation.setDuration(duration);
- }
2、Activity
首先,定义两个布局文件,用于旋转的画面切换
main.xml
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/layout_main"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
- ...
- </LinearLayout>
next.xml
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/layout_next"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
- ...
- </LinearLayout>
限于篇幅,完整布局文件请详见源码 ^_^
然后,初始化两个旋转的布局文件资源
- private void initMain(){
- setContentView(R.layout.main);
- layoutmain = (LinearLayout)findViewById(R.id.layout_main);
- btn_MainLast = (Button)findViewById(R.id.main_last);
- btn_MainNext = (Button)findViewById(R.id.main_next);
- btn_MainLast.setOnClickListener(listener);
- btn_MainNext.setOnClickListener(listener);
- }
- private void initNext(){
- setContentView(R.layout.next);
- layoutnext = (LinearLayout)findViewById(R.id.layout_next);
- btn_NextLast = (Button)findViewById(R.id.next_last);
- btn_NextNext = (Button)findViewById(R.id.next_next);
- btn_NextLast.setOnClickListener(listener);
- btn_NextNext.setOnClickListener(listener);
- }
最后,设置布局文件中的按钮监听事件,响应3D旋转动画和方向
- private View.OnClickListener listener = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.main_last: // 上一页
- layoutmain.startAnimation(lQuest1Animation); // 当前页向左旋转(0,-90)
- initNext();
- layoutnext.startAnimation(lQuest2Animation); // 下一页向左旋转(90, 0)
- break;
- case R.id.main_next: // 下一页
- layoutmain.startAnimation(rQuest1Animation); // 当前页向右旋转(0,90)
- initNext();
- layoutnext.startAnimation(rQuest2Animation); // 下一页向右旋转(-90, 0)
- break;
- case R.id.next_last:
- layoutnext.startAnimation(lQuest1Animation);
- initMain();
- layoutmain.startAnimation(lQuest2Animation);
- break;
- case R.id.next_next:
- layoutnext.startAnimation(rQuest1Animation);
- initMain();
- layoutmain.startAnimation(rQuest2Animation);
- break;
- }
- }
- };
Android 滑动效果进阶篇(五)—— 3D旋转的更多相关文章
- Android 滑动效果进阶篇(六)—— 倒影效果
上篇介绍了使用Animation实现3D动画旋转翻页效果,现在介绍图片倒影实现,先看效果图 本示例主要通过自定义Gallery和ImageAdapter(继承自BaseAdapter)实现 1.倒影绘 ...
- Android 滑动效果入门篇(二)—— Gallery
Gallery 是Android官方提供的一个View容器类,继承于AbsSpinner类,用于实现页面滑动效果. 从上面的继承关系可以看出,AbsSpinner类继承自AdapterView,因此我 ...
- Android 滑动效果入门篇(一)—— ViewFlipper
ViewFilpper 是Android官方提供的一个View容器类,继承于ViewAnimator类,用于实现页面切换,也可以设定时间间隔,让它自动播放.又ViewAnimator继承至于Frame ...
- Android 滑动效果高级篇(八)—— 自定义控件
自定义控件,较常用View.ViewGroup.Scroller三个类,其继承关系如下: 本示例自定义控件,实现一个Gallery效果,并添加了一个显示View个数和位置的bar条,效果图: 自定义控 ...
- Android 滑动效果基础篇(四)—— Gallery + GridView
Android系统自带一个GridView和Gallery两个控件,GridView网格显示,Gallery单个浏览,两者结合起来可以真正实现Gallery浏览图片效果. 本示例通过GridView和 ...
- Android 滑动效果基础篇(三)—— Gallery仿图像集浏览
Android系统自带一个Gallery浏览图片的应用,通过手指拖动时能够非常流畅的显示图片,用户交互和体验都很好. 本示例就是通过Gallery和自定义的View,模仿实现一个仿Gallery图像集 ...
- Android 滑动效果高级篇(七)—— 华丽翻页效果
By 何明桂(http://blog.csdn.net/hmg25) 转载请注明出处 之前看到像ipad上的ibook的模拟书籍翻页的特效感觉很炫,在android上也有像laputa和ireader ...
- 十六、Android 滑动效果汇总
Android 滑动效果入门篇(一)—— ViewFlipper Android 滑动效果入门篇(二)—— Gallery Android 滑动效果基础篇(三)—— Gallery仿图像集浏览 And ...
- Android 滑动效果汇总
Android 滑动效果入门篇(一)—— ViewFlipper Android 滑动效果入门篇(二)—— Gallery Android 滑动效果基础篇(三)—— Gallery仿图像集浏览 And ...
随机推荐
- poj 1026(置换群)
题意:给你一个变换规则,和一个字符串,问经过k次变换后得到的字符串. 思路:开始的时候试图去找它的整个周期,谁知道周期太大了,各种RE,后来在得知此题需要用置换群来优化,第一次接触置换群学习了下! 代 ...
- STM32的JTAG、SWD和串口下载的问题
最近有一个项目用到STM32,为了使PCB布线方便一些所以改了一些引脚,占用了JTAG接口的PA15和PB3,所以要禁用一下JTAG,下载采用SWD模式.这样在实际操作中做出一些总结(方法网上都有.这 ...
- PHP 实现下载文件的方法
方法一: header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); ...
- bzoj 3884 上帝与集合的正确用法(递归,欧拉函数)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3884 [题意] 求2^2^2… mod p [思路] 设p=2^k * q+(1/0) ...
- makefile、gdb使用记录
makefile的模板 all: rover server station rover: rover.c tcputil.o gcc rover.c tcputil.o -o rover -lpthr ...
- javascript !!作用
javaScript中使用!!表示取得boolean值,具体作用如下 var value= !!test[1]; 取变量的Boolean值, 相当于 var value = test[1]?true: ...
- homework 08_2 C++11新特性作业之二
---恢复内容开始--- 1.使用Lambda表达式计算“hello world!”中字母e和i的数量 下面是代码: #include "stdafx.h" #include< ...
- (转载)Java之外观模式(Facade Pattern)
1.概念 为子系统中的一组接口提供一个统一接口.Facade模式定义了一个高层接口,这个接口使得这子系统更容易使用. 2.UML 3.代码 下面是一个具体案例的代码: package facade; ...
- 通过源码学Java基础:BufferedReader和BufferedWriter
准备写一系列Java基础文章,先拿Java.io下手,今天聊一聊BufferedReader和BufferedWriter BufferedReader BufferedReader继承Writer, ...
- POJ 3177 Redundant Paths(强连通分量)
题目链接:http://poj.org/problem?id=3177 题目大意是一个无向图给你n个点m条边,让你求出最少加多少条边 可以让任意两个点相通两条及以上的路线(每条路线点可以重复,但是每条 ...