Crazy Android书中属性动画实例的完整代码及问题

来源:互联网 发布:支持python的虚拟主机 编辑:程序博客网 时间:2024/04/28 15:09

书中存在问题:

(1)动画ObjectAnimator改变的是对象ShapeHolder中变量的值。因此,在使用ShapeDrawable绘制图像之前,一定要将对象ShapeHolder中的属性更新到ShapeDrawable中去。否则,附在对象ShapeHolder中的动画其实没有生效。下图中(1)处代码时必须要添加的,要不然透明动画其实没有生效。

书中该实例中OnDraw函数中代码为(这段代码有问题):


应该为:


(2)另外,使用alpha设置透明的时候,要注意接口接收的是[0, 255]还是[0,1],例如Drawable对象接收的是前者。如果不注意,会发现设置透明好像没有用。

整个完整的代码如下:

MainActivity.java //程序入口

package com.example.attributeanimationtest;


import java.util.ArrayList;


import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.os.Bundle;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.widget.LinearLayout;


public class MainActivity extends Activity {

public static final int BALL_SIZE = 50;
public static final int DURATION = 1000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        LinearLayout ll = (LinearLayout)findViewById(R.id.container);
        ll.addView(new MyView(this));
    }
    
    class MyView extends View implements AnimatorUpdateListener {
   
    @Override
public void onAnimationUpdate(ValueAnimator animation) {
// TODO Auto-generated method stub
this.invalidate();
}


ArrayList<ShapeHolder> balls = new ArrayList<ShapeHolder>();
    public MyView(Context context) {
    super(context);
    setBackgroundColor(Color.WHITE);
   
    }
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
if (event.getAction() != MotionEvent.ACTION_DOWN &&
event.getAction() != MotionEvent.ACTION_MOVE) {
return false;
}
ShapeHolder shapeHolder = addBall(event.getX(), event.getY());
float startY = shapeHolder.getY();
float height = getHeight();
float endY = height - BALL_SIZE;
float y = event.getY();
int durationTime = (int)((height-y) / height * DURATION);

/*
ObjectAnimator fallAnim = ObjectAnimator.ofFloat(shapeHolder, "y", startY, endY);
fallAnim.setDuration(durationTime);
fallAnim.setInterpolator(new AccelerateInterpolator());
fallAnim.addUpdateListener(this);
//fallAnim.start();
*/


ObjectAnimator fadeAnim = ObjectAnimator.ofFloat(shapeHolder, "alpha", 1.0f, 0.0f);
fadeAnim.setDuration(2500);
fadeAnim.addListener(new AnimatorListenerAdapter() {


@Override
public void onAnimationEnd(Animator animation) {
// TODO Auto-generated method stub
balls.remove(((ObjectAnimator)animation).getTarget());
}

});
fadeAnim.addUpdateListener(this);
fadeAnim.start();

/*
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(fallAnim).before(fadeAnim);
animatorSet.start();*/

return true;
}

private ShapeHolder addBall(float x, float y) {
OvalShape shp = new OvalShape();
shp.resize(BALL_SIZE, BALL_SIZE);

ShapeDrawable shpDrawable = new ShapeDrawable(shp);
ShapeHolder shapeHolder = new ShapeHolder(shpDrawable);
shapeHolder.setX(x-BALL_SIZE/2);
shapeHolder.setY(y-BALL_SIZE/2);

int red = (int)(Math.random() * 255);
int green = (int)(Math.random() * 255);
int blue = (int)(Math.random() * 255);

int color = 0xff000000 + red << 16 | green << 8 | blue;
int darkColor = 0xff000000 | red / 4 << 16 | green / 4 << 8 | blue / 4;
RadialGradient rg = new RadialGradient(37.5f, 12.5f, BALL_SIZE, color, darkColor, Shader.TileMode.CLAMP);
Paint paint = shpDrawable.getPaint();
paint.setShader(rg);
shapeHolder.setPaint(paint);
balls.add(shapeHolder);

return shapeHolder;
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
for (ShapeHolder shp: balls) {
canvas.save();
canvas.translate(shp.getX(), shp.getY());
shp.getShape().setAlpha((int)(shp.getAlpha()*255)); //animator只改ShapeHolder变量,并没有改变drawable中状态值
shp.getShape().draw(canvas);
canvas.restore();
}
}
   

    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
}


//ShapeHolder.java //对象: 动画Animator依附的对象。

package com.example.attributeanimationtest;


import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.drawable.ShapeDrawable;


public class ShapeHolder {
private float x = 0;
private float y = 0;
private ShapeDrawable shape;
private int color;
private RadialGradient gradient;
private float alpha = 1f;
private Paint paint;

public ShapeHolder(ShapeDrawable shp) {
shape = shp;
}

public void setX(float xx) {
x = xx;
}
public void setY(float yy) {
y = yy;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public void setShape(ShapeDrawable shpDrawable) {
shape = shpDrawable;
}
public ShapeDrawable getShape() {
return shape;
}
public void setColor(int clr) {
color = clr;
}
public int getColor() {
return color;
}

public void setGradient(RadialGradient rg) {
this.gradient = rg;
}
public RadialGradient getGradient() {
return this.gradient;
}
public void setAlpha(float alpha1) {
this.alpha = alpha1;
}
public float getAlpha() {
return this.alpha;
}
public void setPaint(Paint paint) {
this.paint = paint;
}
public Paint getPaint() {
return this.paint;
}


}


0 0
原创粉丝点击