自定义两端为椭圆形的进度条

1.定义属性

<declare-styleable name="DownloadProgress">
        <attr name="borderColor" format="color" />
        <attr name="borderWidth" format="dimension" />
        <attr name="downloadingCompleteColor" format="color" />
        <attr name="downloadingUnCompleteColor" format="color" />
        <attr name="pauseCompleteColor" format="color" />
        <attr name="pauseUnCompleteColor" format="color" />
        <attr name="progress" format="float" />
        <attr name="textSize" format="dimension" />
        <attr name="downloading" format="boolean" />
        <attr name="showProgressText" format="boolean" />
    </declare-styleable>

2.定义逻辑

public class DownloadProgress extends View {

    private int mWidth;
    private int mHeight;
    private int borderColor;
    private float borderWidth;
    private int downloadingCompleteColor, downloadingUnCompleteColor;
    private int pauseCompleteColor, pauseUnCompleteColor;
    private float mProgress;
    private float mTextSize;

    public void setmProgress(float mProgress) {
        this.mProgress = mProgress;
        invalidate();
    }

    public void setDownloading(boolean downloading) {
        this.downloading = downloading;
        invalidate();
    }

    public void setInfo(float mProgress, boolean downloading){
        this.mProgress = mProgress;
        this.downloading = downloading;
        invalidate();
    }

    private boolean downloading;
    private boolean showProgressText;

    private Paint paint;

    public DownloadProgress(Context context) {
        this(context, null);
    }

    public DownloadProgress(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DownloadProgress(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(attrs, defStyle);
    }

    private void init(AttributeSet attrs, int defStyle) {
        // Load attributes
        final TypedArray a = getContext().obtainStyledAttributes(
                attrs, R.styleable.DownloadProgress, defStyle, 0);

        borderColor = a.getColor(R.styleable.DownloadProgress_borderColor, Color.WHITE);
        borderWidth = a.getDimension(R.styleable.DownloadProgress_borderWidth, 2);
        downloadingCompleteColor = a.getColor(R.styleable.DownloadProgress_downloadingCompleteColor, Color.parseColor("#009FDA"));
        downloadingUnCompleteColor = a.getColor(R.styleable.DownloadProgress_downloadingUnCompleteColor, Color.parseColor("#43CBFD"));
        pauseCompleteColor = a.getColor(R.styleable.DownloadProgress_pauseCompleteColor, Color.parseColor("#9EA1A2"));
        pauseUnCompleteColor = a.getColor(R.styleable.DownloadProgress_pauseUnCompleteColor, Color.parseColor("#D3DBDE"));
        mProgress = a.getFloat(R.styleable.DownloadProgress_progress, 0);
        mTextSize = a.getDimension(R.styleable.DownloadProgress_textSize, 30);
        downloading = a.getBoolean(R.styleable.DownloadProgress_downloading, false);
        showProgressText = a.getBoolean(R.styleable.DownloadProgress_showProgressText, false);

        a.recycle();

        paint = new Paint();
        paint.setFlags(Paint.ANTI_ALIAS_FLAG);
        paint.setTextAlign(Paint.Align.LEFT);
        paint.setTextSize(mTextSize);
    }

    private void drawBorder(Canvas canvas, int w, int h, float r){
        paint.setColor(borderColor);
        paint.setStrokeWidth(borderWidth);

        Path path = new Path();
        RectF rectF = new RectF(0, 0, w, h);
        path.addRoundRect(rectF, r, r, Path.Direction.CW);
        canvas.drawPath(path, paint);
    }

    private void drawMain(Canvas canvas, float w, float h, float r, int color){
        paint.setColor(color);
        paint.setStrokeWidth(1);

        Path path = new Path();
        RectF rectF = new RectF(borderWidth, borderWidth, w + borderWidth, h + borderWidth);
        path.addRoundRect(rectF, r, r, Path.Direction.CW);
        canvas.drawPath(path, paint);
    }

    private void drawLeftArc(Canvas canvas, float completeWidth, float r, float left, float top){
        float angle = (float) (Math.acos((r - completeWidth) / r) * 180 / Math.PI);
        float startAngle = 180 - angle;
        float sweepAngle = angle * 2;
        paint.setColor(downloading ? downloadingCompleteColor : pauseCompleteColor);
        canvas.drawArc(new RectF(left, top, left + r * 2, top + r * 2), startAngle, sweepAngle,false, paint);
    }

    private void drawRightArc(Canvas canvas, float w, float completeWidth, float r, float left, float top){
        float angle = (float) (Math.acos((completeWidth- w + r) / r) * 180 / Math.PI);
        float startAngle = 0 - angle;
        float sweepAngle = angle * 2;
        paint.setColor(downloading ? downloadingUnCompleteColor : pauseUnCompleteColor);
        canvas.drawArc(new RectF(left, top, left + r * 2, top + r * 2), startAngle, sweepAngle,false, paint);
    }

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

        mWidth = getMeasuredWidth();
        mHeight = getMeasuredHeight();
        float r = mHeight  / 2;

        float w = mWidth - borderWidth * 2;
        float h = mHeight - borderWidth * 2;
        float innerR = h / 2;
        float completeWidth = w * mProgress / 100;

        drawBorder(canvas, mWidth, mHeight, r);

        if(completeWidth < innerR){
            drawMain(canvas, w, h, innerR, downloading ? downloadingUnCompleteColor : pauseUnCompleteColor);
            drawLeftArc(canvas, completeWidth, innerR, borderWidth, borderWidth);
        }else if(completeWidth > w - innerR){
            drawMain(canvas, w, h, innerR, downloading ? downloadingCompleteColor : pauseCompleteColor);
            drawRightArc(canvas, w, completeWidth, innerR, mWidth - borderWidth - innerR * 2, borderWidth);
        }else {
            drawMain(canvas, w, h, innerR, downloading ? downloadingUnCompleteColor : pauseUnCompleteColor);
            drawLeftArc(canvas, innerR, innerR, borderWidth, borderWidth);

            paint.setColor(downloading ? downloadingCompleteColor : pauseCompleteColor);
            canvas.drawRect(borderWidth + innerR, borderWidth, borderWidth + completeWidth, borderWidth + innerR * 2, paint);
        }

        if(showProgressText){
            String testString = String.format("%.1f", mProgress) + "%";
            paint.setColor(Color.WHITE);
            paint.setTextAlign(Paint.Align.LEFT);
            Rect bounds = new Rect();
            paint.getTextBounds(testString, 0, testString.length(), bounds);
            Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();
            int baseline = (mHeight - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;
            canvas.drawText(testString,mWidth / 2 - bounds.width() / 2, baseline, paint);
        }


    }

}

3.使用

<com.testandroid.DownloadProgress
        android:id="@+id/dp"
        android:layout_width="800px"
        android:layout_height="200px"
        app:showProgressText="true"
        app:borderWidth="5px"
        app:progress="88"/>


猜你喜欢

转载自blog.csdn.net/ronaldo4511/article/details/80668192