Android自定義View--圓形進度條RoundProgress
阿新 • • 發佈:2019-01-11
要實現的效果
需要知道的知識點
- 字型的高度和寬度是怎麼測?
字型的高度就是textSize的大小。
字型的寬度怎麼測量呢?Paint畫筆中有測量字型寬度的api,如下:
//測量字型的寬度
float width = mPaint.measureText(mProgerss + "%");
- 字型的原點在哪裡?
預設在字型的左下角(在drawText中用到,我們必須要讓字型在控制元件中間) - 圓的半徑怎麼確定?
例如我們要畫下圖黃色的圓
那麼我們的半徑是紅色那段還是黑色那段呢?,如圖所示(黑色代表圓心到外切正方形的距離,紅色代表黑色線段距離減去圓形線寬的一半的距離)。
答案是紅色那段
自定義控制元件第一步–自定義屬性
在values新建attrs.xml檔案,定義屬性,如下所示
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RoundProgress">
<!--背景圓形顏色 -->
<attr name="bgColor" format="color"/>
<!--進度條顏色 -->
<attr name ="roundColor" format="color"/>
<!--進度條及背景圓形的寬度 -->
<attr name="roundWidth" format="dimension"/>
<!--中心字型的大小 -->
<attr name="roundTextSize" format="dimension"/>
<!--中心字型的顏色 -->
<attr name="roundTextColor" format="color"/>
</declare-styleable>
</resources>
自定義控制元件第二步–繼承view
package rc.loveq.roundprogress;
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.util.AttributeSet;
import android.view.View;
/**
* Author:Rc
* Csdn:http://blog.csdn.net/loveqrc
* 0n 2016/12/12 16:36
* Email:[email protected]
*/
public class RoundProgress extends View {
private static final int DEFAULT_BG_COLOR = Color.GRAY;
private static final int DEFAULT_ROUND_COLOR = Color.RED;
private static final float DEFAULT_TEXT_SIZE = 16;
private static final float DEFAULT_ROUND_WIDTH = 10;
private static final int DEFAULT_TEXT_COLOR = Color.BLACK;
private int mBgColor;
private int mRoundColor;
private float mTextSize;
private float mRoundWidth;
private int mTextColor;
private Paint mPaint;
private int mCenterY;
private int mCenterX;
private float mRadius;
private RectF mRectF;
private int mProgerss=0;
public RoundProgress(Context context) {
this(context,null);
}
public RoundProgress(Context context, AttributeSet attrs) {
this(context,attrs,0);
}
public RoundProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = getResources().obtainAttributes(attrs, R.styleable.RoundProgress);
//拿到在xml配置的屬性,如果沒有配置,就使用預設的。
mBgColor = a.getColor(R.styleable.RoundProgress_bgColor, DEFAULT_BG_COLOR);
mRoundColor = a.getColor(R.styleable.RoundProgress_roundColor, DEFAULT_ROUND_COLOR);
mTextSize = a.getDimension(R.styleable.RoundProgress_roundTextSize, DEFAULT_TEXT_SIZE);
mRoundWidth = a.getDimension(R.styleable.RoundProgress_roundWidth, DEFAULT_ROUND_WIDTH);
mTextColor = a.getColor(R.styleable.RoundProgress_roundTextColor, DEFAULT_TEXT_COLOR);
a.recycle();//釋放資源
init();//初始化畫筆
}
private void init() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
}
/**
* 當layout大小變化後會回撥次方法
* 通過這方法獲取寬高
* @param w
* @param h
* @param oldw
* @param oldh
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mCenterX = w/2;//控寬的中心點
mCenterY = h/2;//控制元件高的中心點
//防止寬高不一致
int min = Math.min(mCenterX, mCenterY);
//半徑
mRadius = min-mRoundWidth/2;
//為畫圓弧準備
mRectF = new RectF(mCenterX-mRadius,mCenterY-mRadius,mCenterX+mRadius,mCenterY+mRadius);
}
@Override
protected void onDraw(Canvas canvas) {
// super.onDraw(canvas); 我們自己來畫
//1、先畫背景圓環
mPaint.setColor(mBgColor);
mPaint.setStrokeWidth(mRoundWidth);
canvas.drawCircle(mCenterX, mCenterY,mRadius,mPaint);
//2、畫動態圓弧
mPaint.setColor(mRoundColor);
canvas.drawArc(mRectF,0, (float) (3.6*mProgerss),false,mPaint);
//3、畫中間的文字
mPaint.setColor(mTextColor);
mPaint.setStrokeWidth(0);//如果不設定回0,很難看
mPaint.setTextSize(mTextSize);
//測量字型的寬度
float width = mPaint.measureText(mProgerss + "%");
canvas.drawText(mProgerss+"%",mCenterX-width/2,mCenterY+mTextSize/2,mPaint);
}
public void setProgerss(int progerss){
mProgerss=progerss;
postInvalidate();
}
}
自定義控制元件第三步–在佈局中使用
- 在根節點宣告自定義名稱空間
xmlns:app="http://schemas.android.com/apk/res-auto"
- 引用控制元件
<rc.loveq.roundprogress.RoundProgress
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:id="@+id/rp"
android:layout_width="160dp"
android:layout_height="160dp"
app:bgColor="@android:color/darker_gray"
app:roundColor="@android:color/holo_red_dark"
app:roundWidth="10dp"
app:roundTextColor="#18b4ed"
app:roundTextSize="16sp"
/>