1.在values下面新建一個attrs.xml,如今裏面定義咱們的自定義屬性,android
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="RoundProgressBar"> <attr name="roundColor" format="color"></attr> <attr name="roundProgressColor" format="color"></attr> <attr name="roundWidth" format="dimension"></attr> <attr name="textColor" format="color"></attr> <attr name="textSize" format="dimension"></attr> <attr name="max" 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> </resources>
二、建立一個customView 自定義view類 canvas
package com.example.customprogress; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Typeface; import android.util.AttributeSet; import android.view.View; public class RoundProgressBar extends View { private Paint mPaint; //畫筆 private int roundColor; //圓環的顏色 private int roundProgressColor; //圓環進度的顏色 private int textColor; //百分比字符串的顏色 private float textSize; //百分比字體的大小 private float roundWidth;//圓環的寬度 private int max;//最大進度 private int progerss;//當前進度 private boolean textIsDisplayable; //是否顯示 private int style;//進度風格 public static final int STROKE = 0; public static final int FILL = 1; //第一步重寫因此構造方法 public RoundProgressBar(Context context) { super(context,null); // TODO Auto-generated constructor stub } public RoundProgressBar(Context context, AttributeSet attrs) { super(context, attrs); //建立畫筆對象 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); // 第二步 初始化自定義屬性 initAttrs(context,attrs); } public RoundProgressBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } //第三步 重寫onDraw方法 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //畫圓環 int center = getWidth()/2; //獲取圓形的x座標 int radius =(int)(center-roundWidth/2); //圓環的半徑 mPaint.setColor(roundColor);//設置圓環的顏色 mPaint.setStyle(Paint.Style.STROKE);//空心 mPaint.setStrokeWidth(roundWidth);//寬度 //畫出圓環 canvas.drawCircle(center, center, radius, mPaint); //畫進度百分比 mPaint.setStrokeWidth(0); mPaint.setColor(textColor); mPaint.setTextSize(textSize); mPaint.setTypeface(Typeface.DEFAULT_BOLD);//設置字體 //計算中間的進度百分比,先轉換成float在進行除法運算,否則都爲0 int percent = (int)(((float)progerss/ (float)max) * 100); float textWidth = mPaint.measureText(percent+"%");//獲取字體寬度 if(textIsDisplayable&&percent!=0&&style==STROKE) { //畫出中間進度值 canvas.drawText(percent+"%",center-textWidth/2, center+textSize/2, mPaint); } //畫圓弧 mPaint.setStrokeWidth(roundWidth); mPaint.setColor(roundProgressColor);//圓弧進度顏色 RectF oval = new RectF(center-radius, center-radius,center+radius, center+radius); switch (style) { case STROKE: mPaint.setStyle(Paint.Style.STROKE); canvas.drawArc(oval,0,360*progerss/max, false,mPaint);//根據進度畫圓弧 break; case FILL: //填充的圓 mPaint.setStyle(Paint.Style.FILL_AND_STROKE); if(progerss!=0) { canvas.drawArc(oval, 0, 360*progerss/max,true, mPaint); } break; } } public synchronized int getMax() { return max; } public synchronized void setMax(int max) { if(max<0) { throw new IllegalArgumentException("max not less than 0"); } this.max = max; } public synchronized int getProgress() { return progerss; } public synchronized void setProgress(int progress) { if(progress<0){ throw new IllegalArgumentException("progress not less than 0"); } if(progress>max){ this.progerss = max; } if(progress<max){ this.progerss = progress; } postInvalidate();//刷新界面調用postInvalidate()能在非UI線程中刷新 } public int getCricleColor() { return roundColor; } public void setCricleColor(int cricleColor) { this.roundColor = cricleColor; } public int getCricleProgressColor() { return roundProgressColor; } public void setCricleProgressColor(int cricleProgressColor) { this.roundProgressColor = cricleProgressColor; } public int getTextColor() { return textColor; } public void setTextColor(int textColor) { this.textColor = textColor; } public float getTextSize() { return textSize; } public void setTextSize(float textSize) { this.textSize = textSize; } public float getRoundWidth() { return roundWidth; } public void setRoundWidth(float roundWidth) { this.roundWidth = roundWidth; } //初始化自定義屬性 private void initAttrs(Context context,AttributeSet attrs) { //獲取TypedArray 對象 獲得自定義屬性 TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.RoundProgressBar); //初始化屬性 roundColor = typedArray.getColor(R.styleable.RoundProgressBar_roundColor,Color.RED ); roundProgressColor = typedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor,Color.GREEN); textColor = typedArray.getColor(R.styleable.RoundProgressBar_textColor,Color.GREEN); textSize = typedArray.getDimension(R.styleable.RoundProgressBar_textSize, 15); roundWidth = typedArray.getDimension(R.styleable.RoundProgressBar_roundWidth,5); max = typedArray.getInteger(R.styleable.RoundProgressBar_max,100); textIsDisplayable = typedArray.getBoolean(R.styleable.RoundProgressBar_textIsDisplayable,true); style = typedArray.getInt(R.styleable.RoundProgressBar_style,0); //必定要注意 用完TypedArray 對象 要回收 typedArray.recycle(); } }
三、在佈局文件中使用自定義Viewless
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android_custom="http://schemas.android.com/apk/res/com.example.customprogress" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" tools:context=".MainActivity" > <com.example.customprogress.RoundProgressBar android:id="@+id/custom_progress" android:layout_width="80dp" android:layout_height="80dp" android_custom:roundColor="#4f5f6f" android_custom:textColor="#9a32cd" android_custom:roundProgressColor="#f00" android_custom:textIsDisplayable="true" android_custom:roundWidth="10dp" android_custom:textSize="18sp" android_custom:style="STROKE" /> </LinearLayout>