繁体   English   中英

Android:以编程方式动画自定义Drawable

[英]Android: Animate Custom Drawable programmatically

我有一个自定义类扩展Drawable,如下所示,用于绘制弧。 从我的MainActivity控制Drawable,我基于一些输入值重绘它,我转换为形状的适当“角度”。 例如

这是drawable的初始状态: 在此输入图像描述

这是drawable的第二个状态: 在此输入图像描述 红色箭头表示我想要实现的动作

我试图通过一个动作“动画”从状态1到状态2的变化。 有关如何做到这一点的任何想法? 我应该多次重绘形状,逐渐在第一和第二状态之间转换吗?

我的可绘制代码:

public class CircleLoadingBar extends Drawable implements Drawable.Callback{

private Paint paint;
private Canvas canvas;
private float angle;
private RectF outterCircle;
private float padding=30;

public void invalidateDrawable(Drawable drawable){
    final Callback callback = getCallback();
    if (callback != null) {
        callback.invalidateDrawable(this);
    }
}

public void scheduleDrawable(Drawable drawable, Runnable runnable, long l){
    invalidateDrawable(drawable);
}

public void unscheduleDrawable(Drawable drawable,Runnable runnable){
    //empty
}

public CircleLoadingBar(){
    this(0);
}

public CircleLoadingBar( int angle){
    this.angle=angle;
    this.canvas=new Canvas();

    paint=new Paint();
    paint.setColor(Color.GREEN);
    paint.setStrokeWidth(padding);
    paint.setAntiAlias(true);
    paint.setStrokeCap(Paint.Cap.ROUND);
    paint.setStyle(Paint.Style.STROKE);
    outterCircle = new RectF();
}

public void setAngle(float angle){
    this.angle=angle;
}

@Override
public void draw(Canvas canvas){

    canvas.save();

    Rect bounds = getBounds();

    outterCircle.set(bounds.left+padding,bounds.top+padding,bounds.right-padding,bounds.bottom-padding);

    int[] colors = {Color.RED, Color.GREEN, Color.RED};
    float[] positions = {0,0.2f,1.3f};
    SweepGradient gradient3 = new SweepGradient(innerCircle.centerX(), innerCircle.centerY(),colors,positions);

    paint.setShader(gradient3);

    canvas.drawArc(outterCircle,90,angle,true,paint);

}

@Override
public void setAlpha(int alpha) {
    // Has no effect
}

@Override
public void setColorFilter(ColorFilter cf) {
    // Has no effect
}

@Override
public int getOpacity() {
    // Not Implemented
    return 0;
}
}

我的主要活动代码:

public class MainActivity {


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate();
    setContentView(R.layout.main);
    textView= (TextView) findViewById(R.id.textview);
    circleLoadingBar= new CircleLoadingBar(10);
    textView.setBackgroundDrawable(circleLoadingBar);

}

  public void stateUpdate(float angle) {

        circleLoadingBar.setAngle(angle);
        textView.invalidate();
}
}

经过大量的搜索,我找到了答案。

简介:我需要我的Custom Drawable类来实现Drawable.Callback和Runnable接口(参见下面的代码)。

CustomDrawable.class

public class CustomDrawable extends Drawable implements Drawable.Callback, Runnable{

    private Paint paint;
    private Canvas canvas;
    private int angle;
    private RectF circle;
    private float cx,cy;
    private float mHeight,mWidth=100;
    private float mRadius=20;
    private Drawable.Callback cb;
    private boolean running=false;


    public void invalidateDrawable(Drawable drawable){
        super.invalidateSelf(); //This was done for my specific example. I wouldn't use it otherwise
    }


    public void scheduleDrawable(Drawable drawable, Runnable runnable, long l){
        invalidateDrawable(drawable);
    }

    public void unscheduleDrawable(Drawable drawable,Runnable runnable){
        super.unscheduleSelf(runnable);
    }

    public CircleLoadingBar(){
        this(0);
    }

    public CircleLoadingBar(int angle){
        this.angle=angle;

        paint=new Paint();
        paint.setColor(Color.GREEN);
        paint.setAntiAlias(true);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setStyle(Paint.Style.STROKE);

        circle= new RectF();
    }


    @Override
    public void draw(Canvas canvas){

        canvas.save();

        Rect bounds = getBounds();

        circle.set(bounds);
        canvas.drawArc(circle, 90, angle, true, paint);

    }

    public void nextFrame(){
        unscheduleSelf(this);
        scheduleSelf(this, SystemClock.uptimeMillis() + 250);
    }

    public void stop(){
        running=false;
        unscheduleSelf(this);
    }

    public void start(){
        if(!running){
            running=true;
            nextFrame();
        }
    }

    public void run(){
        angle++;
        invalidate();
        nextFrame();
    }

    @Override
    public void setAlpha(int alpha) {
        // Has no effect
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        // Has no effect
    }

    @Override
    public int getOpacity() {
        // Not Implemented
        return 0;
    }
  }

现在您的Drawable实现了两者,您可以将其作为单独的线程“运行”,由您的活动通过启动和停止功能启动和控制。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM