Android Animation学习(三) ApiDemos解析:XML动画文件的使用

  可以用XML文件来定义Animation。

  文件必须有一个唯一的根节点:

  <set>, <objectAnimator>, or <valueAnimator>三者之一。

  对应的Java类是:

  <set>标签是可以嵌套的。

  <set>标签的android:ordering属性规定了这个set中的动画的执行顺序。该属性值默认是together (default)。

  比如:

<set android:ordering="sequentially" >

    <set>
<objectAnimator
android:duration="500"
android:propertyName="x"
android:valueTo="400"
android:valueType="intType" />
<objectAnimator
android:duration="500"
android:propertyName="y"
android:valueTo="300"
android:valueType="intType" />
</set> <objectAnimator
android:duration="500"
android:propertyName="alpha"
android:valueTo="1f" /> </set>

 

  

  使用时:

        AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(
myContext, R.anim.property_animator);
set.setTarget(myObject);
set.start();

  为了区分Property animation和View animation的资源文件,从Android 3.1开始,Property animation的xml文件存在res/animator/目录下(View animation的存在res/anim/目录下), animator这个名是可选的。但是如果你想要使用Eclipse ADT plugin (ADT 11.0.0+)的布局编辑器,你就必须使用res/animator/目录,因为ADT只在该目录下寻找property animation的资源文件。

Api Demo相关代码:

  代码结构和上一篇文章中的基本类似,也是各种小球的动画,只不过这次的动画效果都是从XML文件中读取的。

  完整的项目见项目地址:https://github.com/mengdd/AnimationApiDemos.git

public class AnimationFromXmlActivity extends Activity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置布局,布局xml中只包含了一个线性布局和一个Button
setContentView(R.layout.animation_basic); LinearLayout container = (LinearLayout) findViewById(R.id.container); // 将自定义的View加入到线性布局中
final MyAnimationView animView = new MyAnimationView(this);
container.addView(animView); // Button的点击事件即动画开始
Button starter = (Button) findViewById(R.id.startButton);
starter.setOnClickListener(new View.OnClickListener() { public void onClick(View v) {
animView.startAnimation();
}
});
} public class MyAnimationView extends View implements
ValueAnimator.AnimatorUpdateListener { private static final float BALL_SIZE = 100f; public final ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
Animator animation = null; public MyAnimationView(Context context) {
super(context);
addBall(50, 50);
addBall(200, 50);
addBall(350, 50);
addBall(500, 50, Color.GREEN);
} private void createAnimation() {
Context appContext = AnimationFromXmlActivity.this; if (animation == null) { // ========================================================
// 载入根节点为<objectAnimator>的xml资源文件,解析放进ObjectAnimator类对象
ObjectAnimator anim = (ObjectAnimator) AnimatorInflater
.loadAnimator(appContext, R.anim.object_animator);
anim.addUpdateListener(this);
anim.setTarget(balls.get(0)); // ========================================================
// 载入根节点为<animator>的xml资源文件,解析放进ValueAnimator类对象
ValueAnimator fader = (ValueAnimator) AnimatorInflater
.loadAnimator(appContext, R.anim.animator);
fader.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
invalidate();
// ValueAnimator动画需要在监听器中自己设置对象的属性值
// 这里改变的是alpha值
balls.get(1).setAlpha(
(Float) animation.getAnimatedValue());
}
}); // ========================================================
// 载入根节点为<set>的xml资源文件,解析放进AnimatorSet类对象
AnimatorSet seq = (AnimatorSet) AnimatorInflater.loadAnimator(
appContext, R.anim.animator_set);// x和y属性同时改变的动画集合
seq.setTarget(balls.get(2));
// 这里要注意:因为AnimatorSet没有设置AnimatorUpdateListener的方法,
// 所以如果其他动画没有设置AnimatorUpdateListener来进行View的invalidate()刷新,
// 这个AnimatorSet seq是不刷新的 // ========================================================
// 载入根节点为<objectAnimator>的xml资源文件,解析放进ObjectAnimator类对象
ObjectAnimator colorizer = (ObjectAnimator) AnimatorInflater
.loadAnimator(appContext, R.anim.color_animator);
colorizer.setTarget(balls.get(3));
colorizer.addUpdateListener(this); // ========================================================
// 总的AnimationSet,所有的动画同时播放
animation = new AnimatorSet();
((AnimatorSet) animation).playTogether(anim, fader, seq,
colorizer);
}
} public void startAnimation() {
createAnimation();
animation.start();
} private ShapeHolder createBall(float x, float y) {
OvalShape circle = new OvalShape();
circle.resize(BALL_SIZE, BALL_SIZE);
ShapeDrawable drawable = new ShapeDrawable(circle);
ShapeHolder shapeHolder = new ShapeHolder(drawable);
shapeHolder.setX(x);
shapeHolder.setY(y);
return shapeHolder;
} private void addBall(float x, float y, int color) {
ShapeHolder shapeHolder = createBall(x, y);
shapeHolder.setColor(color);
balls.add(shapeHolder);
} private void addBall(float x, float y) {
ShapeHolder shapeHolder = createBall(x, y);
int red = (int) (100 + Math.random() * 155);
int green = (int) (100 + Math.random() * 155);
int blue = (int) (100 + Math.random() * 155);
int color = 0xff000000 | red << 16 | green << 8 | blue;
Paint paint = shapeHolder.getShape().getPaint();
int darkColor = 0xff000000 | red / 4 << 16 | green / 4 << 8 | blue
/ 4;
RadialGradient gradient = new RadialGradient(37.5f, 12.5f, 50f,
color, darkColor, Shader.TileMode.CLAMP);
paint.setShader(gradient);
balls.add(shapeHolder);
} @Override
protected void onDraw(Canvas canvas) {
// 遍历并绘制每一个球形对象
for (ShapeHolder ball : balls) {
// 这里是canvas.translate到一个地方,进行绘制,之后再translate回来
// 跟先save后restore的作用相同
canvas.translate(ball.getX(), ball.getY());
ball.getShape().draw(canvas);
canvas.translate(-ball.getX(), -ball.getY());
}
} public void onAnimationUpdate(ValueAnimator animation) { // 刷新View
invalidate(); // 因为第一个小球用的是ObjectAnimator,所以这里不必要自己设置属性值
// 如果是ValueAnimator就需要加上下面两行
// ShapeHolder ball = balls.get(0);
// ball.setY((Float) animation.getAnimatedValue());
}
}
}

相关动画:

  资源文件:

  第一个小球:下落,并且返回:

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:valueTo="200"
android:valueType="floatType"
android:propertyName="y"
android:repeatCount="1"
android:repeatMode="reverse"/>

  第二个小球:消失(变为透明),然后再出现:

<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType"
android:repeatCount="1"
android:repeatMode="reverse"/>

  第三个小球:X轴与Y轴同时运动,并且返回:

<set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:valueTo="200"
android:valueType="floatType"
android:propertyName="x"
android:repeatCount="1"
android:repeatMode="reverse"/>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:valueTo="400"
android:valueType="floatType"
android:propertyName="y"
android:repeatCount="1"
android:repeatMode="reverse"/>
</set>

  第四个小球:颜色变化:

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:valueFrom="#0f0"
android:valueTo="#00ffff"
android:propertyName="color"
android:repeatCount="1"
android:repeatMode="reverse"/>

参考资料

  API Guides:Declaring Animations in XML

  Animation Resources

  项目地址:https://github.com/mengdd/AnimationApiDemos.git

Android Animation学习(三) ApiDemos解析:XML动画文件的使用的更多相关文章

  1. Android开发学习---使用XmlPullParser解析xml文件

    Android中解析XML的方式主要有三种:sax,dom和pull关于其内容可参考:http://blog.csdn.net/liuhe688/article/details/6415593 本文将 ...

  2. Android Animation学习 实现 IOS 滤镜退出动画

    IOS的用户体验做的很好,其中一点很重要的地方就是动画效果. 最近在学习Android的Animation,简单实现了一个IOS相机滤镜退出的动画: 布局文件:activity_animation_d ...

  3. Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition

    Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition Property animation系统还提供了对ViewGroup中的View改变 ...

  4. Android Animation学习(四) ApiDemos解析:多属性动画

    Android Animation学习(四) ApiDemos解析:多属性动画 如果想同时改变多个属性,根据前面所学的,比较显而易见的一种思路是构造多个对象Animator , ( Animator可 ...

  5. Android Animation学习(二) ApiDemos解析:基本Animators使用

    Android Animation学习(二) ApiDemos解析:基本Animatiors使用 Animator类提供了创建动画的基本结构,但是一般使用的是它的子类: ValueAnimator.O ...

  6. Android Animation学习(二) ApiDemos解析:基本Animatiors使用

    Animator类提供了创建动画的基本结构,但是一般使用的是它的子类: ValueAnimator.ObjectAnimator.AnimatorSet ApiDemos中Animation部分是单独 ...

  7. Android Animation学习(一) Property Animation原理介绍和API简介

    Android Animation学习(一) Property Animation介绍 Android Animation Android framework提供了两种动画系统: property a ...

  8. Android Animation学习(六) View Animation介绍

    Android Animation学习(六) View Animation介绍 View Animation View animation系统可以用来执行View上的Tween animation和F ...

  9. Android animation学习笔记之view/drawable animation

    前一章中总结了android animation中property animation的知识和用法,这一章总结View animation和Drawable animation的有关知识: View ...

随机推荐

  1. 原创:C语言打开、下载、删除网页,统计网页字符个数

    本程序由本人在华夏联盟的ID闪电笨笨原创,首发地址:http://bbs.hx95.com/ 写此程序希望可以可以激发新手学习C语言的积极性! C语言代码实现功能如下:            1.实现 ...

  2. 基于HTML5的3D网络拓扑树呈现

    在HT for Web中2D和3D应用都支持树状结构数据的展示,展现效果各异,2D上的树状结构在展现层级关系明显,但是如果数据量大的话,看起来就没那么直观,找到指定的节点比较困难,而3D上的树状结构在 ...

  3. 关于Entity Framework中的Attached报错相关解决方案的总结

    关于Entity Framework中的Attached报错的问题,我这里分为以下几种类型,每种类型我都给出相应的解决方案,希望能给大家带来一些的帮助,当然作为读者的您如果觉得有不同的意见或更好的方法 ...

  4. 图论 --- spfa + 链式向前星 (模板题) dlut 1218 : 奇奇与变形金刚

    1218: 奇奇与变形金刚 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 130  Solved: 37[Submit][Status][Web Boa ...

  5. orleans/Documentation

    福利 奥尔良的主要好处是︰开发人员工作效率,甚至为非专家程序员;和默认的透明可伸缩性与程序员没有特别努力.我们扩大每个下面这些好处. 开发人员的生产力 奥尔良的编程模型通过提供以下关键的抽象. 担保和 ...

  6. 【C#】在窗体中水平居中的控件,到了XP下不居中的解决办法

    我时不时会遭遇这个操蛋问题,今天得闲研究了一下,解决如下: A.将窗体FormBorderStyle属性改为Fixed系,当然这会导致用户不能拖拉窗口大小,所以你可能需要B计划↓ B.确保在[VS]中 ...

  7. JsonConvert 使用注意事项之 Serializable

    1.使用NuGet安装Newtonsoft.Json. 2.创建需要序列化的类. public class Person { public string Name{get;set;} public i ...

  8. 炉石传说 C# 开发笔记 (初版)

    法术资料说明 1.资料的准备 从GitHub上面获得的工程里面,是没有XML卡牌资料配置的,这个是需要你自己生成的. 打开炉边处说的客户端 然后按下  卡牌资料生成 将炉石资料文件设定为 Github ...

  9. SSH实例(5)

    在src中新建struts.xml文件: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE ...

  10. 关于mybatis 的mapper namespace 作用及解析

    因为语言惯性,大部分的namespace 在语言级别*来说是作为一种限定性标识来用,起到唯一或一类的标识.来看看语言(以PHP语言为例)上的namespace的作用实例 一.namespace 在PH ...