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 ...
随机推荐
- codeforces 678D Iterated Linear Function 矩阵快速幂
矩阵快速幂的题要多做 由题可得 g[n]=A*g[n-1]+B 所以构造矩阵 { g[n] } = {A B} * { g[n-1]} { 1 } {0 1 ...
- 基本输入输出系统BIOS---显示输出
显示器通过显示适配卡与系统相连, 显示适配卡是显示输出的接口卡,照相的显示器是CGA和EGA,目前的显示适配卡是VGA和TVGA,他们都支持两种显示方式,文本显示和图形显示 在BIOS中提供的显示I/ ...
- Python 笔记 : 类和继承
# -*- coding= utf-8 -*- # 文件编码定义的语法规则是: coding[:=]/s*([-/w.]+) # 未指定编码将默认为 : ASCII # 同时要注意物理文件的编码也要 ...
- 【转】Yahoo!团队:网站性能优化的35条黄金守则
Yahoo!的 Exceptional Performance团队为改善 Web性能带来最佳实践.他们为此进行了一系列的实验.开发了各种工具.写了大量的文章和博客并在各种会议上参与探讨.最佳实践的核心 ...
- bzoj 2393 Cirno的完美算数教室(容斥原理+搜索)
[题意] 定义C数为只包含数字2和9的数,求[L,R]内能被C数整除的个数. [思路] Dfs预处理出C数,并去除其中倍数的情况. Dfs搜索出现情况,奇数加,偶数减,当数值大于R时剪枝. [代码] ...
- Android中Cursor(游标)类的概念和用法
使用过 SQLite 数据库的童鞋对 Cursor 应该不陌生,如果你是搞.net 开发你大可以把Cursor理解成 Ado.net 中的数据集合相当于dataReader.今天特地将它单独拿出来谈, ...
- Linux下gcc和g++编译helloworld
linux C(hello world) 1.使用vi/vim进行编写代码并保存为hello_world.c.如下: 1 2 3 4 5 6 /* This is my first C program ...
- css 超出部分显示省略号
代码: overflow: hidden; white-space: nowrap; text-overflow: ellipsis; 重点代码:text-overflow: ellipsis; 解 ...
- CentOS6 root 用户 vi/vim 无法开启高亮
编辑 /etc/profile.d/vim.sh if [ -n "$BASH_VERSION" -o -n "$KSH_VERSION" -o -n &quo ...
- 为Android游戏接入第三方登录功能
1. “游戏客户端”调用“SDK客户端”的登录功能向“SDK服务端”进行身份认证 2. 验证通过后,“游戏客户端”可得到用户信息,根据游戏逻辑可将用户信息传给“游戏服务器”进行验证 3. “游戏服务器 ...