-1
A
回答
0
我創建了一個可以繪製所需形狀的視圖。 它首先創建一個宿舍的路徑,然後將畫布旋轉90度以繪製路徑4次。用於繪製Path
的Paint
由progress/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);
}
}
相關問題
- 1. Android NDK:自定義預構建步驟?
- 2. 與自定義步驟和libary
- 3. 自定義步驟UISlider
- 4. Android - 自定義進度條
- 5. CSE(自定義搜索引擎)步驟
- 6. VirtueMart自定義結帳步驟
- 7. 進度條,5%步驟
- 8. Eclipse,CDT,在「clean」步驟中添加自定義步驟
- 9. jQuery UI滑塊自定義步驟
- 10. JqueryUi微調自定義步驟
- 11. Windows Phone Slider的自定義步驟
- 12. d3.js自定義曲線步驟
- 13. coffeescript的自定義預處理步驟?
- 14. 創建自定義視圖的步驟
- 15. VirtueMart 2自定義結帳步驟
- 16. 黃瓜不識別定義的步驟「未定義的步驟」
- 17. 黃瓜:未定義步驟雖然步驟被定義
- 18. 自定義水平進度條與自定義選擇器
- 19. QCustomPlot上的自定義刻度步驟 - QT
- 20. 步驟定義不確認
- 21. 自定義構建步驟中的自動版本文件步驟
- 22. Android Espresso與自定義資源同步
- 23. 自定義鍵盤 - Android電子
- 24. 自定義進度
- 25. 使自定義電子表格與Python
- 26. 步驟將Android APK文件部署到Android電子市場?
- 27. 實現android自定義進度條
- 28. 自定義進度條在android
- 29. Android自定義進度條操作
- 30. Android自定義進度視圖