android_自定義View_圓形百分比顯示

佈局中使用

佈局文件添加命名空間xmlns:attr="http://schemas.android.com/apk/res/.ui"

<packname.RoundProgressBar

                android:layout_centerHorizontal="true"

                android:id="@+id/flow_percent_pie"

                android:layout_width="100dp"

                android:layout_height="100dp"

                attr:roundProgressBarWidth="6dp"

                attr:roundColor="@color/gray"

                attr:textSize="12dp"

                attr:roundProgressColor="#68c630"

                attr:textColor="#68c630"

                attr:textIsDisplayable="true"

                />

自定義屬性

<!--圓形進度條-->

    <declare-styleable name="RoundProgressBar">

        <attr name="roundColor" format="color"/>

        <attr name="roundProgressColor" format="color"/>

        <attr name="roundProgressBarWidth" format="dimension"></attr>

        <attr name="textColor" format="color" />

        <attr name="textSize" format="dimension" />

        <attr name="maxProgressBar" format="integer"></attr>

        <attr name="textIsDisplayable" format="boolean"></attr>

        <attr name="style">

            <enum name="STROKE" value="0"></enum>

            <enum name="FILL" value="1"></enum>

        </attr>

    </declare-styleable>

自定義實現
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
public class RoundProgressBar extends View {
 
    /**
     * 畫筆對象的引用
     */
    private Paint paint;
 
    /**
     * 圓環的顏色
     */
    private int roundColor;
 
    /**
     * 圓環進度的顏色
     */
    private int roundProgressColor;
 
    /**
     * 中間進度百分比的字符串的顏色
     */
    private int textColor;
 
    private String text;
    /**
     * 中間進度百分比的字符串的字體
     */
    private float textSize;
 
    /**
     * 圓環的寬度
     */
    private float roundWidth;
 
    /**
     * 最大進度
     */
    private int max;
 
    /**
     * 當前進度
     */
    private int progress;
 
    /**
     * 是否顯示中間的進度
     */
    private boolean textIsDisplayable;
 
    /**
     * 進度的風格,實心或者空心
     */
    private int style;
 
    public static final int STROKE = 0;
    public static final int FILL = 1;
 
    public RoundProgressBar(Context context) {
        this(context, null);
    }
 
    public RoundProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
 
    public RoundProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray mTypedArray = context.obtainStyledAttributes(attrs,
                R.styleable.RoundProgressBar);
        //獲取自定義屬性和默認值
        roundColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundColor, Color.RED);
        roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor, Color.GREEN);
        textColor = mTypedArray.getColor(R.styleable.RoundProgressBar_textColor, Color.GREEN);
        textSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_textSize, 15);
        roundWidth = mTypedArray.getDimension(R.styleable.RoundProgressBar_roundProgressBarWidth, 5);
        max = mTypedArray.getInteger(R.styleable.RoundProgressBar_maxProgressBar, 100);
        textIsDisplayable = mTypedArray.getBoolean(R.styleable.RoundProgressBar_textIsDisplayable, true);
        style = mTypedArray.getInt(R.styleable.RoundProgressBar_style, 0);
 
        mTypedArray.recycle();
        init(context);
    }
 
    private void init(Context context) {
        paint = new Paint();
    }
 
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /**
         * 畫最外層的大圓環
         */
        int centre = getWidth()/2//獲取圓心的x座標
        int radius = (int) (centre - roundWidth/2); //圓環的半徑
        paint.setColor(roundColor); //設置圓環的顏色
        paint.setStyle(Paint.Style.STROKE); //設置空心
        paint.setStrokeWidth(roundWidth); //設置圓環的寬度
        paint.setAntiAlias(true);  //消除鋸齒
        canvas.drawCircle(centre, centre, radius, paint); //畫出圓環
        /**
         * 畫進度百分比
         */
        paint.setStrokeWidth(0);
        paint.setColor(textColor);
        paint.setTextSize(textSize);
        paint.setTypeface(Typeface.DEFAULT_BOLD); //設置字體
        int percent = (int)(((float)progress / (float)max) * 100);  //中間的進度百分比,先轉換成float在進行除法運算,不然都爲0
        float textWidth = paint.measureText("500M");   //測量字體寬度,我們需要根據字體的寬度設置在圓環中間
 
        if(textIsDisplayable && percent != 0 && style == STROKE){
            canvas.drawText(text.substring(0,2), centre - textWidth , centre - textSize/2, paint); //畫出進度百分比
            canvas.drawText(text.substring(2), centre - textWidth/2, centre + textSize/2, paint); //畫出進度百分比
        }
        /**
         * 畫圓弧 ,畫圓環的進度
         */
        //設置進度是實心還是空心
        paint.setStrokeWidth(roundWidth); //設置圓環的寬度
        paint.setColor(roundProgressColor);  //設置進度的顏色
        RectF oval = new RectF(centre - radius, centre - radius, centre
                + radius, centre + radius);  //用於定義的圓弧的形狀和大小的界限
 
        switch (style) {
            case STROKE:{
                paint.setStyle(Paint.Style.STROKE);
                canvas.drawArc(oval, 180360 * progress / max, false, paint);  //根據進度畫圓弧
                break;
            }
            case FILL:{
                paint.setStyle(Paint.Style.FILL_AND_STROKE);
                if(progress !=0)
                    canvas.drawArc(oval, 0360 * progress / max, true, paint);  //根據進度畫圓弧
                break;
            }
        }
    }
 
    /**
     * 設置進度,此爲線程安全控件,由於考慮多線的問題,需要同步
     * 刷新界面調用postInvalidate()能在非UI線程刷新
     * @param progress
     */
    public synchronized void setProgress(int progress) {
        if(progress < 0){
            throw new IllegalArgumentException("progress not less than 0");
        }
        if(progress > max){
            progress = max;
        }
        if(progress <= max){
            this.progress = progress;
            postInvalidate();
        }
    }
 
    public void setText(String text){
        this.text = text;
        postInvalidate();
    }
}
發佈了33 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章