當拿起畫筆繪畫時真是有種筆墨流塵的感覺呢。
雖然做android有段時間,但是對自定義控件其實并不是非常了解比較慚愧,最近正好需求中有個布局可以自定義控件,也正好趁著這次機會去熟悉一下自定義控件步驟和方法。
需要實現的效果就是上圖這樣,一個進度條然后幾個指示器,進度條上在繪制幾個圓形,不是很復雜的控件,既然有進度條那么正好繼承ProgressBar,這樣可以使用默認樣式。
制作這個控件的時候以下幾點我感覺是比較需要注意的。
1.尺寸
2.畫布
3.畫筆
4.位置
測量
在生活中如果想要繪畫,那么必須物品的就是畫布和畫筆,只要有了它們那么就可以畫出任何想要的東西。
在繪制一幅圖畫的時候畫布的尺寸是需要考慮的,它與你所要描繪的物品展現的思想密切相關,畫布小了可能描繪不全,大了整體展現的空洞,總要適中才好。
那么首先就要確定畫布的尺寸
/**
* 測量
* 這里的寬高只是被繼承的ProgressBar的值,實際的控件大小還需要根據其他的值來確定
* 比如按照這個自定義控件效果來說,除了中間的進度條的大小,
* 還需要知道頂部指示器(文字)的最大高度,以及底部指示器(文字)的最大高度
* 當然如果你還設置了padding,那么還需要加上padding top/bottom
* @param widthMeasureSpec 布局文件中layout_width的值
* @param heightMeasureSpec 布局文件中layout_height的值
*/
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
}
繪制
好了現在到了使用畫筆的時候了,首先當拿起畫筆后需要確定第一筆畫什么,在哪里畫要畫什么顏色,怎樣用力使用什么技巧。
/**
* 繪制
*
* @param canvas
*/
@Override
protected synchronized void onDraw(Canvas canvas) {
...//之前的一些操作
canvas.save();//保存當前畫布狀態
canvas.translate(0, 0);//調整原點位置
...//調整畫布并使用畫筆繪畫
canvas.restore();//取出上一次保存的內容
}
筆觸
即使現實繪畫中也需要不同的筆觸來繪畫,程序中當然也提供了非常多的筆觸以供選擇,在繪畫中需要對這些筆觸熟練運用才能繪制出美好的畫作。
topStartPaint.setTextSize();
topStartPaint.setColor();
設置好畫筆之后自然要選擇起筆的位置
選擇繪畫形狀以及位置和使用哪種畫筆
根據效果圖,首先來畫一個文字
canvas.drawText(text,x,y,paint);
text 要寫的文字
x 文字左側起始x坐標
y 文字baseline坐標
同理只要在測量時獲取到足夠的寬高信息,就可以計算出所要繪畫圖形的位置
canvas.drawCircle(x,y,r,paint);
x,y 圓心x,y坐標
r 半徑
還有其他一些可以繪制的圖形,比如線、矩形、橢圓等,只要你在需要繪制相關圖形時查找一下相關方法即可,只要能明白畫布、畫筆以及位置的關系,相信制作一個自定義控件并不難。
自定義控件自然少不了需要自定義屬性
attrs
在attrs文件中添加相關屬性,format是屬性的相關類型
<declare-styleable name="IndicatorProgressBar">
<!--頂部提示器默認文字顏色,尺寸-->
<attr name="topTextColor" format="color"/>
<attr name="topTextSize" format="dimension"/>
<!--頂部提示器高亮文字顏色,尺寸-->
<attr name="topLightTextColor" format="color"/>
<attr name="topLightTextSize" format="dimension"/>
<!--圓點默認顏色和高亮顏色-->
<attr name="pointColor" format="color"/>
<attr name="pointLightColor" format="color"/>
<!--頂部開始提示器-->
<attr name="topStartText" format="string"/>
<!--頂部中間提示器-->
<attr name="topContentText" format="string"/>
<!--頂部末尾提示器-->
<attr name="topEndText" format="string"/>
<!--底部提示器文字顏色,尺寸-->
<attr name="btmTextColor" format="color"/>
<attr name="btmTextSize" format="dimension"/>
...
</declare-styleable>
layout xml
使用前檢查是否增加了
xmlns:app="http://schemas.android.com/apk/res-auto"
使用app:xx=""的方式來添加屬性值
<IndicatorProgressBar
app:topTextColor="#ffffffff"
.../>
IndicatorProgressBar class
TypedArray typedArray = getContext()
.obtainStyledAttributes(attrs, R.styleable.IndicatorProgressBar);
//根據你所設置的format 在class中獲取相關屬性 typedArray.getString typedArray.getColor
typedArray.recycle();
這樣一個簡單的自定義控件基本上就完成了,可以在layout布局中實時查看控件樣式。
因為控件相對簡單,并且使用到的筆觸和圖形也不多,所以有很多效果都沒有很好的體現,并且在繪制中出現了圖層重疊的情況也還沒有進行優化,如果文章中還有什么問題也請告知我,Thanks!