2016-03-29 45 views

回答

0

我創建了一個可以繪製所需形狀的視圖。 它首先創建一個宿舍的路徑,然後將畫布旋轉90度以繪製路徑4次。用於繪製PathPaintprogress/maxProgress決定。

我使用第二個路徑來表示繪圖時剪輯出的畫布區域,以便在各個宿舍之間有空的空間。

最後,可以在恢復畫布旋轉和剪裁後在中間繪製文本。

public class CustomProgressView extends View { 

    private int progress; 
    private int maxProgress; 

    private float arcWidth; 
    private float arcPadding; 
    private Paint paintPositive; 
    private Paint paintNegative; 
    private Paint paintText; 

    private Path path; 
    private Path clipPath; 

    private ProgressListener listener; 

    public CustomProgressView(Context context) { 
     super(context); 

     init(); 
    } 

    public CustomProgressView(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     init(); 
    } 

    public CustomProgressView(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 

     init(); 
    } 

    private void init() { 
     arcWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 25, getResources().getDisplayMetrics()); 
     arcPadding = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 6, getResources().getDisplayMetrics()); 

     paintPositive = new Paint(); 
     paintPositive.setColor(Color.RED); 
     paintPositive.setStyle(Paint.Style.FILL_AND_STROKE); 
     paintPositive.setAntiAlias(true); 

     paintNegative = new Paint(); 
     paintNegative.setColor(Color.BLUE); 
     paintPositive.setStyle(Paint.Style.FILL_AND_STROKE); 
     paintNegative.setAntiAlias(true); 

     paintText = new Paint(); 
     paintText.setColor(Color.BLACK); 
     paintText.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 24, getResources().getDisplayMetrics())); 

     progress = 0; 
     maxProgress = 10; 
    } 

    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
     super.onLayout(changed, left, top, right, bottom); 

     float diameter = Math.min(getWidth(), getHeight()); 

     RectF ovalOuter = new RectF(0, 0, diameter, diameter); 
     RectF ovalInner = new RectF(ovalOuter.left + arcWidth, ovalOuter.top + arcWidth, ovalOuter.right - arcWidth, ovalOuter.bottom - arcWidth); 

     path = new Path(); 
     path.moveTo(ovalOuter.centerX(), ovalOuter.top); 
     path.addArc(ovalOuter, 270, 90); 
     path.lineTo(ovalInner.right, ovalInner.centerY()); 
     path.addArc(ovalInner, 0, -90); 
     path.lineTo(ovalOuter.centerX(), ovalOuter.top); 

     clipPath = new Path(); 
     clipPath.addRect(ovalOuter.left, ovalOuter.centerY() - arcPadding/2, ovalOuter.right, ovalOuter.centerY() + arcPadding/2, Path.Direction.CW); 
     clipPath.addRect(ovalOuter.centerX() - arcPadding/2, ovalOuter.top, ovalOuter.centerX() + arcPadding/2, ovalOuter.bottom, Path.Direction.CW); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     float perc = (float) progress/(float) maxProgress; 
     int state = 0; 
     if (perc < 0.25) { 
      state = 1; 
     } else if (perc < 0.5) { 
      state = 2; 
     } else if (perc < 0.75) { 
      state = 3; 
     } else { 
      state = 4; 
     } 

     RectF bounds = new RectF(); 
     path.computeBounds(bounds, true); 

     // Draw Circle 
     canvas.save(); 
     // Clip padding 
     canvas.clipPath(clipPath, Region.Op.DIFFERENCE); 

     canvas.drawPath(path, state == 1 ? paintPositive : paintNegative); 

     canvas.rotate(90, bounds.left, bounds.bottom); 
     canvas.drawPath(path, state == 2 ? paintPositive : paintNegative); 

     canvas.rotate(90, bounds.left, bounds.bottom); 
     canvas.drawPath(path, state == 3 ? paintPositive : paintNegative); 

     canvas.rotate(90, bounds.left, bounds.bottom); 
     canvas.drawPath(path, state == 4 ? paintPositive : paintNegative); 
     canvas.restore(); 

     // Draw Progress 
     String text = String.valueOf(progress); 

     Rect textBounds = new Rect(); 
     paintText.getTextBounds(text, 0, text.length(), textBounds); 

     float x = bounds.left - textBounds.width()/2; 
     float y = bounds.bottom + textBounds.height()/2; 
     canvas.drawText(text, x, y, paintText); 
    } 

    public int getProgress() { 
     return progress; 
    } 

    public void setProgress(int progress) { 
     int oldProgress = this.progress; 
     this.progress = progress; 

     if (listener != null) { 
      listener.onProgressChanged(oldProgress, progress); 
     } 

     invalidate(); 
    } 

    public int getMaxProgress() { 
     return maxProgress; 
    } 

    public void setMaxProgress(int maxProgress) { 
     this.maxProgress = maxProgress; 
     invalidate(); 
    } 

    public ProgressListener getListener() { 
     return listener; 
    } 

    public void setListener(ProgressListener listener) { 
     this.listener = listener; 
    } 

    public interface ProgressListener { 
     void onProgressChanged(int oldProgress, int newProgress); 
    } 
}