Android圓環進度載入自定義view
阿新 • • 發佈:2020-12-12
近來自己手敲了一個圓環進度載入的自定義view,這裡用來表示清理系統垃圾的載入,作為了自定義view練手入門。特此分享給大家也練練手。
演示效果:
實現步驟
1.畫背景圓環
2.畫中心文字
3.畫當前進度圓弧
5.畫圓軌跡的同心圓
6.實時更新進度
CircleProgressView程式碼
public class CircleProgressView extends View { /** * 背景圓環paint */ private Paint bgPaint; /** * 進度圓環paint */ private Paint progressPaint, smallCirclePaint; private Paint textPaint1, textPaint2; /** * 背景圓環半徑 */ private int bgRadus = 60; /** * 當前進度百分比,總數為100 */ private int curPercentProgress = 0; /** * 文字顯示內容 */ private String content; private String fixText; public CircleProgressView(Context context) { super(context); init(); } public CircleProgressView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } private void init() { setBgPaint(); setProgressPaint(); setTextPaint(); } private void setBgPaint() { bgPaint = new Paint(); bgPaint.setColor(getResources().getColor(R.color.white)); bgPaint.setStyle(Paint.Style.STROKE); bgPaint.setStrokeWidth(10); bgPaint.setAntiAlias(true); smallCirclePaint = new Paint(); smallCirclePaint.setColor(getResources().getColor(R.color.white)); } private void setProgressPaint() { progressPaint = new Paint(); progressPaint.setColor(getResources().getColor(R.color.orange)); progressPaint.setStyle(Paint.Style.STROKE); progressPaint.setStrokeWidth(14); progressPaint.setAntiAlias(true); } private void setTextPaint() { textPaint1 = new Paint(); textPaint1.setColor(getResources().getColor(R.color.orange)); textPaint1.setTextSize(50); textPaint1.setAntiAlias(true); textPaint2 = new Paint(); textPaint2.setColor(getResources().getColor(R.color.black)); textPaint2.setTextSize(44); textPaint2.setAntiAlias(true); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //圓直徑 int bgCircleWidth = dp2px(getContext(), bgRadus * 2); //圓與矩形外邊距 int padding = (getWidth() - bgCircleWidth) / 2; //居中畫背景圓環 RectF rectF = new RectF(padding, padding, padding + bgCircleWidth, padding + bgCircleWidth); canvas.drawArc(rectF, -90, 360, false, bgPaint); Rect contentRect = new Rect(); //畫中心文字 content = "當前" + curPercentProgress * 2 + "M"; //將文字居中顯示,需要獲取文字的寬度,再計算左右邊距 //獲取文字寬度,高度: getTextBounds 是將TextView 的文字放入一個Rect矩形中, 測量TextView的高度和寬度 .witdh() .height()獲取 textPaint1.getTextBounds(content, 0, content.length(), contentRect); canvas.drawText(content, (getWidth() - contentRect.width()) / 2, (getHeight() - contentRect.height()) / 2, textPaint1); fixText = "垃圾檔案"; textPaint2.getTextBounds(fixText, 0, fixText.length(), contentRect); canvas.drawText(fixText, (getWidth() - contentRect.width()) / 2, (getHeight() + contentRect.height() * 2) / 2, textPaint2); //畫進度圓弧 /** * 引數:(中文) * oval - 用於確定圓弧形狀與尺寸的橢圓邊界(即橢圓外切矩形) * startAngle - 開始角度(以時鐘3點的方向為0°,12點鐘為-90°,順時針為正方向) * sweepAngle - 掃過角度 圓弧範圍為 startAngle-startAngle+sweepAngle,如果sweepAngle為0,則不顯示圓弧 * useCenter - 是否包含圓心,true即為扇形,false為圓弧 * paint - 繪製圓弧的畫筆 */ RectF rectFProgress = new RectF(padding, padding, padding + bgCircleWidth, padding + bgCircleWidth); canvas.drawArc(rectFProgress, -90, curPercentProgress * 360 / 100, false, progressPaint); drawThumb(canvas, bgCircleWidth / 2); } /** * 更新當前進度 * * @param progress 進度值範圍 0-100 */ public void updateProgress(int progress) { if (progress < 0 || progress > 100) { return; } curPercentProgress = progress; invalidate(); } private void drawThumb(Canvas canvas, int r) { //畫終端同心圓 float centerX = getWidth() / 2; float centerY = getHeight() / 2; float angle = (float) (curPercentProgress * 360 / 100 * Math.PI / 180); // *Math.PI/180將角度轉為弧度,PI為180度 //需要將圓實時畫在圓進度軌跡上,簡單地用到了三角函式計算,(centerX,centerY)為原點,r為半徑,軌跡方程為x^2+y^2=r^2; x=sin(angle),y=cos(angle) float x = (float) (centerX + r * Math.sin(angle)); float y = (float) (centerY - r * Math.cos(angle)); canvas.drawCircle(x, y, dp2px(getContext(), 4), progressPaint); canvas.drawCircle(x, y, dp2px(getContext(), 3), smallCirclePaint); } public static int dp2px(Context context, int dp) { return (int) (dp * context.getResources().getDisplayMetrics().density); } }
進度更新
public class MainActivity extends AppCompatActivity { private CircleProgressView circleProgressView; private int progress = 0; private Handler handler = new Handler() { @Override public void handleMessage(@NonNull Message msg) { progress += 1; circleProgressView.updateProgress(progress); if (progress == 100) { handler.removeMessages(0); } handler.sendEmptyMessageDelayed(0, 50); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); circleProgressView = findViewById(R.id.progressview); handler.sendEmptyMessageDelayed(0, 1000); } }
好了,以上就是主要實現程式碼, 有錯誤歡迎指出