1 前言
自定義view是android的一個(gè)難點(diǎn),逃避了那么久嗡载, 現(xiàn)在覺(jué)得不會(huì)的東西還是得要從基礎(chǔ)補(bǔ)起來(lái)窑多,自定義進(jìn)度條網(wǎng)上也一大堆,這篇文章只是一個(gè)入門(mén)的學(xué)習(xí)筆記洼滚,高手請(qǐng)略過(guò)...
2 view的工作流程
這里只說(shuō)自定義環(huán)形進(jìn)度條埂息,比較入門(mén)級(jí),所以只做簡(jiǎn)單介紹遥巴,顯得簡(jiǎn)潔千康,看著舒服,后續(xù)會(huì)講詳細(xì)的流程方法铲掐,所以先來(lái)看看view的大體工作流程拾弃。
a) measure 確實(shí)view的測(cè)量寬/高 (測(cè)三圍,看五官)
b) layout 確定view的四個(gè)頂點(diǎn)的位置 (站在舞臺(tái)位置)
c} ondraw 將view繪制到屏幕上 (打扮好出場(chǎng))
3 工作圖
4 流程步驟
- 自定義view的相關(guān)屬性
// 圓環(huán)的顏色
private int ringColor = 0xFF00FF00;
// 圓環(huán)進(jìn)度的顏色
private int ringProgressColor = 0xFFFF0000;
//圓環(huán)的寬度
private int ringWidth = 10;
// 字體大小
private int textSize = 20;
// 字體顏色
private int textColor = 0xFF0000FF;
// 當(dāng)前進(jìn)度
private int currentProgress = 60;
// 最大進(jìn)度
private int maxProgress = 100;
// 得到控件的寬度
private int width;
// 畫(huà)筆對(duì)象
private Paint paint;
- 在values下新建attr.xml
<!-- 自定義環(huán)形進(jìn)度條的屬性-->
<declare-styleable name="RingProgressView">
<attr name="ringColor" format="color"/>
<attr name="ringProgressColor" format="color"/>
<attr name="ringWidth" format="dimension"/>
<attr name="textSize" format="dimension"/>
<attr name="textColor" format="color"/>
<attr name="currentProgress" format="integer"/>
<attr name="maxProgress" format="integer"/>
</declare-styleable>
- 通過(guò)TypedArray獲取自定義view的相關(guān)屬性
public RingProgressView(Context context) {
this(context, null);
}
public RingProgressView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public RingProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
// 得到自定義資源數(shù)組
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RingProgressView);
ringColor = typedArray.getColor(R.styleable.RingProgressView_ringColor, ringColor);
ringProgressColor = typedArray.getColor(R.styleable.RingProgressView_ringProgressColor, ringProgressColor);
ringWidth = (int) typedArray.getDimension(R.styleable.RingProgressView_ringWidth, dip2px(10));
textSize = (int) typedArray.getDimension(R.styleable.RingProgressView_textSize, dip2px(20));
textColor = typedArray.getColor(R.styleable.RingProgressView_textColor, textColor);
currentProgress = typedArray.getInt(R.styleable.RingProgressView_currentProgress, currentProgress);
maxProgress = typedArray.getColor(R.styleable.RingProgressView_maxProgress, maxProgress);
typedArray.recycle();
paint = new Paint();
// 抗鋸齒
paint.setAntiAlias(true);
}
- 畫(huà)同心圓
// 1. 計(jì)算圓心坐標(biāo)及半徑
float centerX = width / 2;
float centerY = width / 2;
float radius = width / 2 - ringWidth / 2;
// 2. 畫(huà)圓環(huán)
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(ringWidth);
paint.setColor(ringColor);
canvas.drawCircle(centerX, centerY, radius, paint);
- 畫(huà)圓弧進(jìn)度
// 3. 畫(huà)圓弧
RectF rectF = new RectF(ringWidth / 2, ringWidth / 2, width - ringWidth / 2, width - ringWidth / 2);
paint.setColor(ringProgressColor);
canvas.drawArc(rectF, 0, currentProgress * 360 / maxProgress, false, paint);
- 畫(huà)百分比文本框
// 3. 畫(huà)文本
String text = currentProgress * 100 / maxProgress + "%";
paint.setColor(textColor);
paint.setTextSize(textSize);
// 要重新設(shè)置寬度為0
paint.setStrokeWidth(0);
// 得到指定文本邊界的指定大小
Rect bounds = new Rect();
paint.getTextBounds(text, 0, text.length(), bounds);
// float textWidth = paint.measureText(text);
// float textHigh = textSize;
canvas.drawText(text, width / 2 - bounds.width() / 2, width / 2 + bounds.height() / 2, paint);
學(xué)習(xí)心得
- 自定義屬性
1.通過(guò)新建attrs.xml迹炼,增加declare-styleable標(biāo)簽來(lái)定義相關(guān)的屬性
2.通過(guò)TypedArray獲取自定義的資源數(shù)組
- getDimension砸彬、getDimensionPixelOffset、getDimensionPixelSize區(qū)別
getDimension和getDimensionPixelOffset的功能都是獲取某個(gè)dimen的值斯入,但是如果單位是dp或sp砂碉,則需要將其乘以density。如果是px刻两,則不乘增蹭。并且getDimension返回float,getDimensionPixelOffset返回int.
而getDimensionPixelSize則不管寫(xiě)的是dp磅摹,sp滋迈,px, 都會(huì)乘以denstiy.
- Paint類(lèi)measureText與getTextBounds的區(qū)別
在使用Canvas繪制文字時(shí)霎奢,需要得到字符串的長(zhǎng)度,Paint類(lèi)內(nèi)給了兩個(gè)方法饼灿,measureText()幕侠,getTextBounds(),但是實(shí)際的寬度meauserText()要比getTextBounds()大一點(diǎn),但是相差不會(huì)太大
- Paint畫(huà)圓的半徑之謎
為什么圓的半徑是radius = width / 2 - ringWidth / 2而不是width / 2 或者width / 2 - ringWidth?
其實(shí)我們畫(huà)的是圓環(huán)碍彭,有寬度的晤硕,Paint畫(huà)刷其實(shí)是從圓環(huán)的中心點(diǎn)繪制的,所以半徑是 width / 2 - ringWidth / 2庇忌,如果你不信舞箍,看下圖:
自定義環(huán)形進(jìn)度條到此結(jié)束,感謝你的瀏覽
完整版代碼:戳這里