`

android实现3D效果翻页

 
阅读更多
 

android实现3D效果翻页

分类: android 879人阅读 评论(3) 收藏 举报

        最近做了一个简单的3D效果翻页特效,先说说我的思路吧,首先我这个翻页效果并不是两个Activity之间的跳转,而是在同一个activity类切换不同的view而已。我现在的做法是单击一个button然后Gone当前的布局,然后把需要呈现的布局visible,在隐藏当前布局的时候启动动画,然后给动画添加监听,在动画结束时开始另外一个view的入场动画就行了。

       下面来看下我的主页面的布局文件:

[html] view plaincopy
 
  1. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:id="@+id/container"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent" >  
  5.   
  6.     <include  
  7.         android:layout_width="fill_parent"  
  8.         android:layout_height="fill_parent"  
  9.         layout="@layout/layout2" />  
  10.   
  11.     <include  
  12.         android:layout_width="fill_parent"  
  13.         android:layout_height="fill_parent"  
  14.         layout="@layout/layout1" />  
  15.   
  16. </FrameLayout>  

我这个布局文件使用<include>标签包含了另外2个布局文件,这些布局文件才是呈现数据的,下面是另外2个布局文件:

layout1:

[html] view plaincopy
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="@drawable/test1"  
  6.     android:orientation="vertical"   
  7.     android:id="@+id/container1"  
  8.     >  
  9.   
  10.     <Button  
  11.         android:id="@+id/bt_towhile"  
  12.         android:layout_width="wrap_content"  
  13.         android:layout_height="wrap_content"  
  14.         android:layout_gravity="center"  
  15.         android:text="白色" />  
  16.   
  17. </LinearLayout>  

layout2:

[html] view plaincopy
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/container2"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:background="@drawable/test2"  
  7.     android:orientation="vertical" >  
  8.   
  9.     <Button  
  10.         android:id="@+id/bt_toblack"  
  11.         android:layout_width="wrap_content"  
  12.         android:layout_height="wrap_content"  
  13.         android:layout_gravity="center"  
  14.         android:text="黑色" />  
  15.   
  16. </LinearLayout>  


我这里只是举个例子并没有放什么实际的类容,只是放了2个button,当我点击其中一个跳转到另外一个layout。

       有了布局文件那我们就开始要实现功能了,我们的想法是点击按钮的时候开始一个动画等动画结束时再开启另外一个动画并隐藏和展示layout1和layout2。

下面是我写的一个动画工具类源码:

[java] view plaincopy
 
  1. package com.test.view;  
  2.   
  3. import android.view.View;  
  4. import android.view.ViewGroup;  
  5. import android.view.animation.Animation;  
  6. import android.view.animation.DecelerateInterpolator;  
  7.   
  8. public class RotateAnimationUtil {  
  9.   
  10.     private ViewGroup context;  
  11.   
  12.     private View[] views;  
  13.   
  14.     public RotateAnimationUtil(ViewGroup context, View... views) {  
  15.         super();  
  16.         this.context = context;  
  17.         this.views = views;  
  18.     }  
  19.   
  20.     /** 
  21.      * 应用自定义的Rotate3DAnimation动画 
  22.      *  
  23.      * @param flag 
  24.      *            当前控件的顺序坐标 
  25.      * @param startDegress 
  26.      *            开始的角度 
  27.      * @param endDegress 
  28.      *            结束的角度 
  29.      */  
  30.     public void applyRotateAnimation(int flag, float startDegress,  
  31.             float endDegress) {  
  32.         final float centerX = context.getWidth() / 2.0f;  
  33.         final float centerY = context.getHeight() / 2.0f;  
  34.   
  35.         Rotate3DAnimation rotate = new Rotate3DAnimation(startDegress,  
  36.                 endDegress, centerX, centerY, 310.0f, true);  
  37.         rotate.setDuration(1000);  
  38.         rotate.setFillAfter(false);  
  39.         rotate.setInterpolator(new DecelerateInterpolator());  
  40.   
  41.         rotate.setAnimationListener(new DisplayNextView(flag));  
  42.         context.startAnimation(rotate);  
  43.     }  
  44.   
  45.     private final class DisplayNextView implements Animation.AnimationListener {  
  46.   
  47.         private final int mFlag;  
  48.   
  49.         private DisplayNextView(int flag) {  
  50.             mFlag = flag;  
  51.         }  
  52.   
  53.         public void onAnimationStart(Animation animation) {  
  54.   
  55.         }  
  56.   
  57.         // 动画结束  
  58.   
  59.         public void onAnimationEnd(Animation animation) {  
  60.             context.post(new SwapViews(mFlag));  
  61.         }  
  62.   
  63.         public void onAnimationRepeat(Animation animation) {  
  64.   
  65.         }  
  66.     }  
  67.   
  68.     /** 
  69.      * 新开一个线程动画结束后再开始一次动画效果实现翻屏特效 
  70.      *  
  71.      * @author yangzhiqiang 
  72.      *  
  73.      */  
  74.     private final class SwapViews implements Runnable {  
  75.   
  76.         private final int mFlag;  
  77.   
  78.         public SwapViews(int mFlag) {  
  79.             this.mFlag = mFlag;  
  80.         }  
  81.   
  82.         public void run() {  
  83.             final float centerX = context.getWidth() / 2.0f;  
  84.             final float centerY = context.getHeight() / 2.0f;  
  85.             Rotate3DAnimation rotation;  
  86.             if (mFlag > -1) {  
  87.                 views[0].setVisibility(View.GONE);  
  88.                 views[1].setVisibility(View.VISIBLE);  
  89.                 views[1].requestFocus();  
  90.                 rotation = new Rotate3DAnimation(270360, centerX, centerY,  
  91.                         310.0f, false);  
  92.             } else {  
  93.                 views[1].setVisibility(View.GONE);  
  94.                 views[0].setVisibility(View.VISIBLE);  
  95.                 views[0].requestFocus();  
  96.                 rotation = new Rotate3DAnimation(900, centerX, centerY,  
  97.                         310.0f, false);  
  98.             }  
  99.             rotation.setDuration(1000);  
  100.             rotation.setFillAfter(false);  
  101.             rotation.setInterpolator(new DecelerateInterpolator());  
  102.             // 开始动画  
  103.             context.startAnimation(rotation);  
  104.   
  105.         }  
  106.   
  107.     }  
  108.   
  109. }  


我解释一下这个类的构造方法:

[java] view plaincopy
 
  1. public RotateAnimationUtil(ViewGroup context, View... views) {  
  2.         super();  
  3.         this.context = context;  
  4.         this.views = views;  
  5.     }  

有2个参数,第一个参数就是我们的主布局页面的FrameLayout,第2个参数就是我们要进行动画切换的2个子layout,我这使用的是一个可变长参数只是为了方便而已。

public void applyRotateAnimation(int flag, float startDegress,float endDegress)方法第一个参数是标记当前是第是从哪个个layout跳转,因外我们必须知道当前开始跳转的layout才能推算角度。

       下面是我自定义动画的源码:

[java] view plaincopy
 
  1. package com.test.view;  
  2.   
  3. import android.graphics.Camera;  
  4. import android.graphics.Matrix;  
  5. import android.view.animation.Animation;  
  6. import android.view.animation.Transformation;  
  7.   
  8. public class Rotate3DAnimation extends Animation {  
  9.   
  10.     private final float mFormDegress;  
  11.   
  12.     private final float mToDegress;  
  13.   
  14.     private final float mCenterX;  
  15.   
  16.     private final float mCenterY;  
  17.   
  18.     /** 
  19.      * 控制z轴的一个常量值,主要是控制动画的升降距离 
  20.      */  
  21.     private final float mDepthz;  
  22.   
  23.     /** 
  24.      * 控制z轴是像上移动还是向下移动,从而实现升降效果 
  25.      */  
  26.     private final boolean mReverse;  
  27.   
  28.     private Camera mCamera;  
  29.   
  30.     public Rotate3DAnimation(float formDegress, float toDegress, float centerX,  
  31.             float centerY, float depthz, boolean reverse) {  
  32.         super();  
  33.         this.mFormDegress = formDegress;  
  34.         this.mToDegress = toDegress;  
  35.         this.mCenterX = centerX;  
  36.         this.mCenterY = centerY;  
  37.         this.mDepthz = depthz;  
  38.         this.mReverse = reverse;  
  39.     }  
  40.   
  41.     @Override  
  42.     public void initialize(int width, int height, int parentWidth,  
  43.             int parentHeight) {  
  44.         super.initialize(width, height, parentWidth, parentHeight);  
  45.         mCamera = new Camera();  
  46.     }  
  47.   
  48.     /** 
  49.      * interpolatedTime 取值范围是0-1之间当每次,当动画启动后会系统会不停的调用applyTransformation方法, 
  50.      * 并改变interpolatedTime的值 
  51.      */  
  52.     @Override  
  53.     protected void applyTransformation(float interpolatedTime, Transformation t) {  
  54.         final float formDegress = mFormDegress;  
  55.         // 通过差点值计算出转变的角度  
  56.         float degress = formDegress  
  57.                 + ((mToDegress - formDegress) * interpolatedTime);  
  58.         final float centerX = mCenterX;  
  59.         final float centerY = mCenterY;  
  60.         final Camera camera = mCamera;  
  61.   
  62.         // 得到当前矩阵  
  63.         Matrix matrix = t.getMatrix();  
  64.         // 报错当前屏幕的状态  
  65.         camera.save();  
  66.         // 判断是降还是升  
  67.         if (mReverse) {  
  68.             // 正向改变Z轴角度  
  69.             camera.translate(0.0f, 0.0f, mDepthz * interpolatedTime);  
  70.         } else {  
  71.             // 反向改变Z轴角度  
  72.             camera.translate(0.0f, 0.0f, mDepthz * (1.0f - interpolatedTime));  
  73.         }  
  74.         // 旋转Y轴角度  
  75.         camera.rotateY(degress);  
  76.         // 把当前改变后的矩阵信息复制给Transformation的Matrix  
  77.         camera.getMatrix(matrix);  
  78.         // 根据改变后的矩阵信息从新恢复屏幕  
  79.         camera.restore();  
  80.   
  81.         // 让动画在屏幕中间运行  
  82.         matrix.preTranslate(-centerX, -centerY);  
  83.         matrix.postTranslate(centerX, centerY);  
  84.     }  
  85. }  

如果你不需要沉降效果那么你把下面的代码删除掉即可:

[java] view plaincopy
 
  1. if (mReverse) {  
  2.             // 正向改变Z轴角度  
  3.             camera.translate(0.0f, 0.0f, mDepthz * interpolatedTime);  
  4.         } else {  
  5.             // 反向改变Z轴角度  
  6.             camera.translate(0.0f, 0.0f, mDepthz * (1.0f - interpolatedTime));  
  7.         }  

好了核心代码已经上完,下面是主界面代码:

[java] view plaincopy
 
  1. package com.test.rotateanimation;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.view.Menu;  
  6. import android.view.View;  
  7. import android.view.ViewGroup;  
  8. import android.widget.Button;  
  9. import android.widget.FrameLayout;  
  10. import android.widget.LinearLayout;  
  11.   
  12. import com.test.view.RotateAnimationUtil;  
  13.   
  14. public class MainActivity extends Activity {  
  15.   
  16.     private FrameLayout container;  
  17.   
  18.     private LinearLayout container1;  
  19.   
  20.     private LinearLayout container2;  
  21.   
  22.     private RotateAnimationUtil rotateAnimationUtil;  
  23.   
  24.     private Button bt_towhile;  
  25.   
  26.     private Button bt_toblack;  
  27.   
  28.     @Override  
  29.     public void onCreate(Bundle savedInstanceState) {  
  30.         super.onCreate(savedInstanceState);  
  31.         setContentView(R.layout.activity_main);  
  32.         initView();  
  33.   
  34.         bt_towhile.setOnClickListener(new View.OnClickListener() {  
  35.   
  36.             @Override  
  37.             public void onClick(View v) {  
  38.                 rotateAnimationUtil.applyRotateAnimation(1090);  
  39.             }  
  40.         });  
  41.         bt_toblack.setOnClickListener(new View.OnClickListener() {  
  42.   
  43.             @Override  
  44.             public void onClick(View v) {  
  45.                 rotateAnimationUtil.applyRotateAnimation(-10, -90);  
  46.             }  
  47.         });  
  48.   
  49.         // 设置当前View控件的缓存  
  50.         container  
  51.                 .setPersistentDrawingCache(ViewGroup.PERSISTENT_ANIMATION_CACHE);  
  52.     }  
  53.   
  54.     private void initView() {  
  55.         container = (FrameLayout) findViewById(R.id.container);  
  56.         bt_toblack = (Button) findViewById(R.id.bt_toblack);  
  57.         bt_towhile = (Button) findViewById(R.id.bt_towhile);  
  58.   
  59.         container1 = (LinearLayout) findViewById(R.id.container1);  
  60.         container2 = (LinearLayout) findViewById(R.id.container2);  
  61.   
  62.         rotateAnimationUtil = new RotateAnimationUtil(container, container1,  
  63.                 container2);  
  64.     }  
  65.   
  66.     @Override  
  67.     public boolean onCreateOptionsMenu(Menu menu) {  
  68.         getMenuInflater().inflate(R.menu.activity_main, menu);  
  69.         return true;  
  70.     }  
  71.   
  72. }  

下面是运行效果,剪切效果不好,呵呵.

 

 

分享到:
评论

相关推荐

    android实现3D翻页效果源码

    总的来说,这个“android实现3D翻页效果源码”项目提供了一个实用的工具,帮助开发者快速地在自己的应用中添加3D翻页效果。通过深入理解并研究源码,不仅可以学习到Android动画系统和自定义View的相关知识,还能提升...

    Android3D翻页效果的倒计时控件

    然后,为了实现3D翻页效果,我们需要使用OpenGL ES或Android的`ViewFlipper`类。OpenGL ES是一个强大的图形库,可以让我们创建复杂的3D动画,但它的学习曲线较陡峭。相比之下,`ViewFlipper`类则更易于上手,它提供...

    ANDROID系统3D翻页效果源代码

    在Android开发中,实现3D翻页效果是一种常见的交互设计,可以增强用户的操作体验,尤其在电子书阅读、画廊应用或动态展示场景中。"ANDROID系统3D翻页效果源代码"提供了一种实现这一效果的方法。接下来,我们将详细...

    3d翻页效果android

    在Android平台上实现3D翻页效果,是一种提升用户体验和视觉吸引力的重要技术,尤其适用于电子书阅读器、杂志或漫画应用。"3d翻页效果android"这个标题所指的就是在Android应用中集成这种动态的、立体感强烈的翻页...

    android 的3d翻页效果

    2. Matrix(矩阵):Android中的Matrix类用于处理几何变换,包括平移、旋转、缩放等,是实现3D翻页效果的重要工具。 3. Animation(动画):Android的Animation框架可以创建平滑的动画效果,如AlphaAnimation(透明...

    android 3D真实翻页效果

    在Android平台上实现3D真实翻页效果是一种提升用户体验的有效方式,尤其在电子书阅读器、杂志应用或互动式UI设计中。这个特定的项目利用了OpenGL ES,一个强大的图形库,来创建逼真的3D翻页动画。接下来,我们将深入...

    Android 利用Camera实现中轴3D卡牌翻转效果

    要实现3D卡牌翻转,我们需要创建两个视图(通常是一个ImageView或自定义View),一个显示卡片的正面,另一个显示背面。这两个视图会分别放置在一个布局中,然后通过调整Camera的参数来改变它们的显示角度,从而实现...

    android电子书翻页效果

    在Android平台上,为电子书实现逼真的翻页效果是一项常见的需求,这能为用户带来更加沉浸式的阅读体验。本文将详细探讨如何在Android应用中创建这样的翻页效果,包括技术原理、实现方法以及可能遇到的问题。 首先,...

    实现多种3D翻页的效果

    实现3D翻页效果的关键在于理解Android的视图渲染和动画系统。Android的动画系统包括Property Animation(属性动画)和View Animation(视图动画)。属性动画允许开发者对对象的属性进行动画化,包括位置、大小、透明...

    Android 3D特效相册+电子书翻页效果

    为了实现3D相册,你需要: 1. **数据结构与模型加载**:创建一个3D模型来表示相册,这可能涉及到将2D图片映射到3D表面上。使用例如Assimp库来导入3D模型或自己解析3D格式(如OBJ、3DS)。 2. **纹理映射**:将用户...

    Android 翻页效果实现源码

    "Android 翻页效果实现源码"是一个关于如何在Android应用中实现这种效果的资源包,其中包含了详细的实现代码和注释。下面我们将深入探讨这个主题,介绍Android翻页效果的基本原理、实现方法以及可能遇到的关键技术点...

    android 电子书翻页效果

    "android 电子书翻页效果"这个话题涉及到的是如何在Android应用中实现类似纸质书翻页的动画效果,让电子阅读更加生动有趣。下面我们将深入探讨这个主题。 首先,Android中的翻页特效通常是通过自定义View或者使用第...

    android pdf 的翻页效果

    在Android平台上实现PDF的翻页效果是一项常见的任务,特别是在开发阅读类应用时。这个话题涉及到多个技术点,包括PDF解析、动画渲染以及用户交互。以下是对这个主题的详细阐述: 1. **PDF解析**:首先,我们需要一...

    Android 实现书籍翻页效果----升级

    在Android开发中,实现书籍翻页效果是一种常见的增强用户体验的技术,尤其在电子阅读应用中尤为重要。这个主题,"Android 实现书籍翻页效果----升级",着重关注的是如何通过编程来模拟真实的纸张翻页动画,使用户在...

    android各种翻页效果,超炫

    在Android开发中,实现炫酷的翻页效果是提升用户体验的重要手段之一。"android各种翻页效果,超炫"这个标题暗示我们将探讨一系列创新且吸引人的页面翻转动画技术,这些技术可以应用于书籍阅读应用、相册展示或者任何...

    android gallery 3D效果

    在Android平台上,`Gallery`组件曾经是实现3D滚动效果的一种流行方式,它允许用户以横向滑动的方式浏览图片或项目列表,同时提供了一种视觉上的立体感。然而,随着Android版本的更新,`Gallery`组件在API 16...

    基于Android实现3D翻页效果

    总之,基于Android实现3D翻页效果涉及到布局设计、动画创建、事件监听和视图切换等多个技术点。通过巧妙地组合和调整这些元素,开发者可以创建出各种独特的翻页交互,提升应用的用户体验。在实际开发中,可以依据...

    Android平台的3D效果

    在Android平台上实现3D效果,可以为用户带来更加生动、直观的交互体验,尤其是在开发应用或游戏时。本文将深入探讨如何在Android中创建类似iPhone的翻页3D效果,主要涉及的技术点包括视图变换、OpenGL ES以及动画...

Global site tag (gtag.js) - Google Analytics