Android中的Animation支持无处不在,不同Activity切换,不同View之间切换,显示列表,显示表格都可以使用动画效果。前面例子Android ApiDemos示例解析(3): App->Activity->Animation 介绍不同Activity切换时淡入淡出动画效果。 Android ApiDemos示例解析(52):Graphics->AnimateDrawables 使用了 AnimationDrawable 显示帧动画。

Android 中 Animation 资源可以分为两种:

  • Tween Animation 对单个图像进行各种变换(缩放,平移,旋转等)来实现动画。
  • Frame Animation 由一组图像顺序显示显示动画

本例主要介绍了两个不同View切换时采用3D旋转效果。 涉及到的Animation却有3个方面:

LayoutAnimation

ListView在Layout中的定义如下:

<ListView
android:id=”@android:id/list”
android:persistentDrawingCache=”animation|scrolling”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:layoutAnimation=”@anim/layout_bottom_to_top_slide” />

Layout animation 用来个一个layout 或是viewgroup 包含的子view添加动画效果,比如本例为ListView 的每个列表项添加一个动画效果@anim/layout_bottom_to_top_slide。 Layout中的每个元素都会采用同一个动画效果,但开始时间不同。

看一下@anim/layout_bottom_to_top_slide” 的定义:

<layoutAnimation xmlns:android=”http://schemas.android.com/apk/res/android”
android:delay=”130%”
android:animationOrder=”reverse”
android:animation=”@anim/slide_right” />

对应LayoutAnimation 可以定义:

  • delay: 定义每个子View开始动画延迟时间。
  • animationOrder: 枚举Layout中子View的顺序,可以为normal (正序),reverse(倒序),random(随机顺序)。
  • animation: 每个子View 所采用的动画效果,本例为@anim/slide_right,效果是文字从左到右移动。
  • interpolator:帧插值算法,定义了动画的变化速率,动画的各帧的显示可以加速,减速,重复显示等。

@anim/slide_right 的定义如下:

<set xmlns:android=”http://schemas.android.com/apk/res/android”
android:interpolator=”@android:anim/accelerate_interpolator”>
<translate android:fromXDelta=”-100%p” android:toXDelta=”0″
android:duration=”1000″ />
</set>

修改了一下duration 的值1 秒,使的更容易看到动画效果。

上面ListView的综合动画效果就是:例表从下到上显示列表项,每个列表项从左到右出现:

Android ApiDemos示例解析(95):Views->Animation->3D Transition_第1张图片下面再来看看两个View ,ListView 和 ImageView 之间如何实现3D 旋转效果的。

两个View在Layout中的定义:

<FrameLayout xmlns:android=”http://schemas.android.com/apk/res/android”
android:id=”@+id/container”
android:layout_width=”match_parent”
android:layout_height=”match_parent”>

<ListView
android:id=”@android:id/list”
android:persistentDrawingCache=”animation|scrolling”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:layoutAnimation=”@anim/layout_bottom_to_top_slide” />

<ImageView
android:id=”@+id/picture”
android:scaleType=”fitCenter”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:visibility=”gone” />

</FrameLayout>

采用的是FrameLayout,所有的子View都对齐到左上角,但imageView 初始为不可见,因此只会看到ListView. 各种Layout定义可以参见Android简明开发教程六:用户界面设计

采用了自定义Animation的方式来实现3D transition .

Rotate3dAnimation 为Animation的子类,Animation为所有动画效果的基类。Rotate3dAnimation实现了可以绕Y轴旋转指定角度的动画效果。

其构造函数定义:

public Rotate3dAnimation(float fromDegrees, float toDegrees,
float centerX, float centerY, float depthZ, boolean reverse)

  • fromDegrees: 开始旋转角度。
  • toDegrees: 旋转结束角度。
  • centerX: 旋转中心X坐标
  • centerY: 旋转中心Y坐标。
  • depthZ: 旋转上Z轴上的距离。
  • reverse: 正转或是反转。

Animation 的子类必须重载applyTransformation

@Overrideprotected void applyTransformation(float interpolatedTime, Transformation t) { final float fromDegrees = mFromDegrees; float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);   final float centerX = mCenterX; final float centerY = mCenterY; final Camera camera = mCamera;   final Matrix matrix = t.getMatrix();   camera.save(); if (mReverse) { camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime); } else { camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime)); } camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore();   matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); }


其中interpolatedTime 为当前动画帧对应的相对时间,值总在0-1之间。

t 为符合所需Animation 对应的Transformation。一般可以根据当前interpolatedTime 根据所需实现动画效果计算并设置对应的Transformation。

本例使用了android.graphics.Camera(非android.hardware.Camera 摄像头设备类)来帮助计算3D Transformation,具体算法见上面代码。

有了这个Rotate3dAnimation ,就可以为View添加3D 旋转切换动画效果。

其核心代码如下:

private void applyRotation(int position, float start, float end) { // Find the center of the container final float centerX = mContainer.getWidth() / 2.0f; final float centerY = mContainer.getHeight() / 2.0f;   // Create a new 3D rotation with the supplied parameter // The animation listener is used to trigger the next animation final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end, centerX, centerY, 310.0f, true); rotation.setDuration(500); rotation.setFillAfter(true); rotation.setInterpolator(new AccelerateInterpolator()); rotation.setAnimationListener(new DisplayNextView(position));   mContainer.startAnimation(rotation); }   public void onItemClick(AdapterView parent, View v, int position, long id) { // Pre-load the image then start the animation mImageView.setImageResource(PHOTOS_RESOURCES[position]); applyRotation(position, 0, 90); }   public void onClick(View v) { applyRotation(-1, 180, 90); }


其中onItemClick 为ListView 点击某个列表项时处理事件,为正向旋转90度。而onClick 为ImageView可见时点击处理事件,为逆向旋转90度(从180度到90度)

applyRotation 中首先创建Rotate3dAnimation 的示例,然后在ViewGroup(mContainer,本例对应FrameLayout)调用startAnimation 启动动画。

rotation.setAnimationListener(new DisplayNextView(position)); 为animation 添加listener ,为动画添加下一个动画效果,本例还是启动一个Rotate3dAnimation用于切换到另一个View.

Android ApiDemos示例解析(95):Views->Animation->3D Transition_第2张图片

更多相关文章

  1. Android实现界面组件的抖动效果
  2. 速读原著-Android应用开发入门教程(3D动画效果的实现)
  3. android 动画详解(二)
  4. Android 自定义Toast
  5. android UI学习 -- 设置界面的布局(包括style的使用,selector的
  6. Android SDK自定义更新
  7. Android应用开发——跑马灯效果
  8. Android 属性动画(Property Animation) 完全解析【附源码】

随机推荐

  1. QT 使用QSqlQuery时候的 错误,。。。。
  2. 字符集问题的初步探讨(五)----如何识别导
  3. SQL:ORDER BY`date`和START WHERE`value`
  4. MYSQL数据库的安装
  5. identity_insert和表初始化脚本
  6. sql语句中各子部分的执行顺序
  7. MySQL 中的函数(一:数学函数)
  8. 3、Oracle PL/SQL中Date格式及格式转换
  9. 浅谈mysql的备份
  10. 1.4.6 收集sql语句的执行计划 2