自定義View(1) - 圓形進度


                   效果圖


package com.github.lzyzsd.circleprogressexample;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

/**
 * @Class: MyCircleView
 * @Description:
 * @author: zm
 * @Date: 2019/7/17 0017
 */
public class MyCircleView extends View {
    //底部圓
    Paint bgCirclePaint;

    //進度圓
    Paint progressCirclePaint;

    //文本
    Paint textPaint;

    //繪製區域
    RectF rectF = new RectF();

    private int progress ;

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

    public MyCircleView(Context context, @Nullable AttributeSet attrs) {
       this(context,attrs,0);
    }

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

    private void init() {
        bgCirclePaint = new Paint();
        bgCirclePaint.setAntiAlias(true);
        bgCirclePaint.setColor(Color.BLACK);

        progressCirclePaint = new Paint();
        progressCirclePaint.setAntiAlias(true);
        progressCirclePaint.setColor(Color.RED);

        textPaint = new Paint();
        textPaint.setTextSize(30f);
        textPaint.setAntiAlias(true);
        textPaint.setColor(Color.WHITE);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //測量高度 此處固定了寬高,類型是 MeasureSpec.EXACTLY ,另外兩種情況未處理
        setMeasuredDimension(widthMeasureSpec,heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        rectF.set(0,0,width,height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //繪製圓
        canvas.drawCircle(getWidth()/2f,getHeight()/2f,getWidth()/2,bgCirclePaint);
        /**
         *   如圖(重點)保持和水平直徑平行,根據進度比計算startAngle 、 sweepAngle
         *   
         *   sweepAngle = progress/100f * 360
         *   
         *   startAngle =90 - sweepAngle/2.0f(兩條水平線的夾角相等)
         *   
         *   以豎直手機屏幕爲準,水平直徑右端點爲繪製圓的起始點,向上爲逆時針(- degree),反之(+degree)
         */
        canvas.drawArc(rectF,90-progress/100f*180,progress/100f*360,false,progressCirclePaint);
        //繪製文本X軸
        float width = getWidth()/2.0f - textPaint.measureText(String.valueOf(progress))/2.0f +getPaddingLeft();
        //文本基線
        float baseLine =  getHeight()/2+(Math.abs(textPaint.ascent())-textPaint.descent())/2;
        //繪製文本
        canvas.drawText(String.valueOf(progress)+"%",width,baseLine,textPaint);

        canvas.save();
    }

    public void setProgress(int progress){
        if (progress<0) {
            progress = 0;
        }
        if (progress>100) {
            progress = 100;
        }
        this.progress = progress;
        invalidate();
    }
    public int getProgress(){
       return progress;
    }
}

角1  = 角2

最近在學自定義view,記錄一下,希望自己在這方面有所突破

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