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

来源:互联网 发布:宏毅网络王欢欢 编辑:程序博客网 时间:2024/05/02 02:54

    可以用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"/>

以上转载:http://www.cnblogs.com/mengdd/archive/2013/09/05/3303403.html

0 0
原创粉丝点击