自定義控件之中間帶文字的環形進度條,重新onMeasure自適配最小寬高問題

這是一片工作日誌記錄,用的比較多所以記錄下來,免得下次又來寫。

繪製過程都是在ondraw方法中執行,思路是首先通過drawCircle畫灰色底圖,然後通過drawArc畫粉色進度條,這中間涉及到這兩個api的繪製時候的半徑問題,主要是arc弧形與它的外切Rect的重合部分要在半徑中去除以達到重合效果。

onMeasure中使用來讀取xml中寫到的半徑,並使用寬高的最小尺寸作爲最後的半徑,此代碼片段具有通用性和借鑑意義,這裏特此記錄:

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final int width = MeasureSpec.getSize(widthMeasureSpec);
        final int height = MeasureSpec.getSize(heightMeasureSpec);
        smallSize=width>height?height:width;
        setMeasuredDimension(smallSize,smallSize);

    }

效果如圖:

SimpleCycleProgressView.java具體代碼如下:
package com.xuganwen.testdrag;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

/**
 * 文件名 SimpleCycleProgressView
 * 文件描述
 * 作者 徐幹穩
 * 創建日期 2020/03/17 16:20
 * 版本 1.0
 */
public class SimpleCycleProgressView extends View {


    private Paint paint;
    private int color = Color.parseColor("#EDEDED");
    private Paint textPaint;

    private String textString = "50";

    private float persent = 0.0f;

    private int smallSize=0;

    public SimpleCycleProgressView(Context context) {
        super(context, null);
    }

    public SimpleCycleProgressView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStrokeWidth(30);
        paint.setColor(color);
        paint.setStyle(Paint.Style.STROKE);

        textPaint = new Paint();
        textPaint.setAntiAlias(true);
        textPaint.setStrokeWidth(5);
        textPaint.setColor(Color.parseColor("#414141"));
        textPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    }

    public SimpleCycleProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final int width = MeasureSpec.getSize(widthMeasureSpec);
        final int height = MeasureSpec.getSize(heightMeasureSpec);
        smallSize=width>height?height:width;
        setMeasuredDimension(smallSize,smallSize);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(smallSize / 2, smallSize / 2, smallSize / 2 - 15, paint);

        RectF rectF = new RectF(15, 15, smallSize - 15, smallSize - 15);
        paint.setColor(Color.parseColor("#EB7F8F"));
        canvas.drawArc(rectF, -90, (float) (persent * 3.6), false, paint);

        textPaint.setTextAlign(Paint.Align.CENTER);
//        paint2.setTypeface(Typeface.defaultFromStyle(Typeface.ITALIC));
        textPaint.setTextSize(smallSize / 8);
        Rect rect = new Rect();
        textPaint.getTextBounds(textString, 0, textString.length(), rect);
        Paint.FontMetricsInt fm = textPaint.getFontMetricsInt();
        int baseLineY = smallSize / 2 + (fm.bottom - fm.top) / 2 - fm.bottom;
        canvas.drawText(textString, smallSize / 2, baseLineY, textPaint);
    }


    public void setColor(String colorString) {
        this.color = Color.parseColor(colorString);
    }


    public void setPersent(float persent) {
        this.persent = persent;
        this.textString = persent+ "%";
    }
}

MainActivity.java代碼中控件使用如下:

   progressview = findViewById(R.id.progressview);

        progressview.setPersent(Float.valueOf("76.5"));
        progressview.invalidate();

layout.xml中聲明如下:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
       android:id="@+id/recycleview"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        android:visibility="gone"
        app:layout_constraintTop_toTopOf="parent" />

    <com.xuganwen.testdrag.SimpleCycleProgressView
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:id="@+id/progressview"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="40dp"
        app:layout_constraintLeft_toRightOf="parent"
        app:layout_constraintRight_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:text="show dialog again"
        android:id="@+id/btn"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

以上就是此控件的所有代碼了,如果大家嫌棄圖形比較僵硬的話,大家可以在控件的構造方法中插入動畫來時環形進度動起來,這裏就不寫了,各位看官從代碼中獲得啓發的給個讚唄~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章