Android Animation学习(三) ApiDemos解析:XML动画文件的使用
Android Animation学习(三) ApiDemos解析:XML动画文件的使用
可以用XML文件来定义Animation。
文件必须有一个唯一的根节点:
<set>, <objectAnimator>, or <valueAnimator>三者之一。
对应的Java类是:
- ValueAnimator - <animator>
- ObjectAnimator - <objectAnimator>
- AnimatorSet - <set>
<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
项目地址:https://github.com/mengdd/AnimationApiDemos.git
Android Animation学习(三) ApiDemos解析:XML动画文件的使用的更多相关文章
- Android开发学习---使用XmlPullParser解析xml文件
Android中解析XML的方式主要有三种:sax,dom和pull关于其内容可参考:http://blog.csdn.net/liuhe688/article/details/6415593 本文将 ...
- Android Animation学习 实现 IOS 滤镜退出动画
IOS的用户体验做的很好,其中一点很重要的地方就是动画效果. 最近在学习Android的Animation,简单实现了一个IOS相机滤镜退出的动画: 布局文件:activity_animation_d ...
- Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition
Android Animation学习(五) ApiDemos解析:容器布局动画 LayoutTransition Property animation系统还提供了对ViewGroup中的View改变 ...
- Android Animation学习(四) ApiDemos解析:多属性动画
Android Animation学习(四) ApiDemos解析:多属性动画 如果想同时改变多个属性,根据前面所学的,比较显而易见的一种思路是构造多个对象Animator , ( Animator可 ...
- Android Animation学习(二) ApiDemos解析:基本Animators使用
Android Animation学习(二) ApiDemos解析:基本Animatiors使用 Animator类提供了创建动画的基本结构,但是一般使用的是它的子类: ValueAnimator.O ...
- Android Animation学习(二) ApiDemos解析:基本Animatiors使用
Animator类提供了创建动画的基本结构,但是一般使用的是它的子类: ValueAnimator.ObjectAnimator.AnimatorSet ApiDemos中Animation部分是单独 ...
- Android Animation学习(一) Property Animation原理介绍和API简介
Android Animation学习(一) Property Animation介绍 Android Animation Android framework提供了两种动画系统: property a ...
- Android Animation学习(六) View Animation介绍
Android Animation学习(六) View Animation介绍 View Animation View animation系统可以用来执行View上的Tween animation和F ...
- Android animation学习笔记之view/drawable animation
前一章中总结了android animation中property animation的知识和用法,这一章总结View animation和Drawable animation的有关知识: View ...
随机推荐
- 聊Javascript中的AOP编程
Duck punch 我们先不谈AOP编程,先从duck punch编程谈起. 如果你去wikipedia中查找duck punch,你查阅到的应该是monkey patch这个词条.根据解释,Mon ...
- sql初始化XML操作
/// <summary> /// 添加记录 /// </summary> /// <param name="sender"></para ...
- Android学习笔记之短信验证码的获取和读取
PS:最近很多事情都拖拖拉拉的..都什么办事效率啊!!! 还得吐槽一下移动运营商,验证码超过五次的时候,直接把我的手机号封闭.真是受够了. 学习笔记: 1.Android之如何获取短信验证码. 2.如 ...
- Windows Azure Cloud Service (41) 修改云服务IIS托管管道模式为4.0经典模式
<Windows Azure Platform 系列文章目录> 这是笔者在之前的项目中遇到的问题,做一下总结,给网友做参考. 在一般情况下,Visual Studio开发的Cloud Se ...
- Windows Azure Service Bus (1) 基础
<Windows Azure Platform 系列文章目录> 我们在基于Windows Azure进行云端开发的时候,云端的软件通常都需要与其他软件进行交互.这些其他软件可能包括其他In ...
- 使用Spark分析拉勾网招聘信息(四): 几个常用的脚本与图片分析结果
概述 前一篇文章,已经介绍了BMR的基础用法,再结合Spark和Scala的文档,我想应该是可以开始你的数据分析之路的.这一篇文章,着重进行一些简单的思路上的引导和分析.如果你分析招聘数据时,卡在了某 ...
- Python性能提升小技巧
第一部分 1-使用内建函数: 你可以用Python写出高效的代码,但很难击败内建函数. 经查证. 他们非常快速 2-使用 join() 连接字符串. 你可以使用 + 来连接字符串. 但由于string ...
- js正则中的贪婪和非贪婪模式问题总结
var b="abeeee:eeeee:eeeeeab"; console.log(b.match(/e+\:e+/g));//["eeee:eeeee"]贪婪 ...
- node.js中使用https请求报CERT_UNTRUSTED的问题解决
只要调用了没有受信的https就会报错:CERT_UNTRUSTED 简单的解决方法就是设置环境变量回避非授信证书的问题. 只要在请求的代码之前加上如下代码即可: process.env.NODE_T ...
- Spring @Transactional propagation 各个属性值的含义
REQUIRED:业务方法需要在一个容器里运行.如果方法运行时,已经处在一个事务中,那么加入到这个事务,否则自己新建一个新的事务. NOT_SUPPORTED:声明方法不需要事务.如果方法没有关联到一 ...