2015-04-30 99 views
3

我有一個自定義類擴展Drawable,如下圖所示,這意味着繪製一個弧。從我的MainActivity控制Drawable,我基於一些輸入值重新繪製它,這些輸入值可以轉換爲形狀的適當「角度」。例如。Android:動畫自定義可編程繪製

這是可拉伸的初始狀態: enter image description here

這是可拉伸的第二狀態:enter image description here 紅色箭頭表示我試圖實現

我試圖運動用掃描運動「動畫」從狀態1到狀態2的變化。任何想法如何做到這一點?我是否應該重新繪製形狀,在狀態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; 
} 
} 

我的MainActivity代碼:

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(); 
} 
} 

回答

2

很多周圍搜索後,我找到了答案。我需要我的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; 
    } 
    } 

現在,您可繪製同時實現,你可以在「運行」它作爲一個單獨的線程,發起並通過啓動你的活動控制和停止功能。