博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android Animation学习(三) ApiDemos解析:XML动画文件的使用
阅读量:4957 次
发布时间:2019-06-12

本文共 5433 字,大约阅读时间需要 18 分钟。

可以用XML文件来定义Animation。

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

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

  对应的Java类是:

  • - <animator>
  • - <objectAnimator>
  • - <set>

 

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

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

  比如:

 

  

  使用时:

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文件中读取的。

  完整的项目见项目地址:

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
balls = new ArrayList
(); 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) { // ======================================================== // 载入根节点为
的xml资源文件,解析放进ObjectAnimator类对象 ObjectAnimator anim = (ObjectAnimator) AnimatorInflater .loadAnimator(appContext, R.anim.object_animator); anim.addUpdateListener(this); anim.setTarget(balls.get(0)); // ======================================================== // 载入根节点为
的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()); } }); // ======================================================== // 载入根节点为
的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是不刷新的 // ======================================================== // 载入根节点为
的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()); } } }

 

相关动画:

  资源文件:

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

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

 

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

  第四个小球:颜色变化:

 

 

参考资料

  API Guides:

  

  项目地址:

转载于:https://www.cnblogs.com/Free-Thinker/p/4384198.html

你可能感兴趣的文章