
記得我的第一個項目是把師兄做好的一個原生app進(jìn)行“加工”,所謂的加工其實就是去網(wǎng)上找一下別人做好的定義控件,然后找來搬到界面上去,當(dāng)時對這些花里胡哨的View完全沒有概念,單純就是覺得“哇,這效果好叼!”,知其然,而不失其所以然。不過還好,現(xiàn)在終于開始了解自定義View到底是為何物。
所謂的自定義View,其實就是開發(fā)者不想千篇一律地使用android系統(tǒng)自帶的控件而利用android的繪圖API來繪制自己想要的效果,創(chuàng)造出屬于自己的個性化控件,它帶來的好處自然不用多說,最重要的是它是我認(rèn)為android開發(fā)最吸引我的地方之一。
通常情況,有以下三種方法來實現(xiàn)自定義控件:
1.對現(xiàn)有控件進(jìn)行拓展
2.通過組合來實現(xiàn)新的控件
3.重寫View來實現(xiàn)新的控件
對現(xiàn)有控件進(jìn)行拓展是一個非常重要的自定義方法,同時也是最基礎(chǔ)的方法,它可以在原生控件的基礎(chǔ)上進(jìn)行拓展,增加新功能、顯示新的UI等等,簡而言之,就是站在巨人的肩膀上對進(jìn)行小修小補(bǔ),而既然是拓展,那必然要“畫”出新的東西,所以一般是在onDraw()方法中對原生控件進(jìn)行拓展。
自定義View我是跟著《Android群英傳》學(xué)的,剛剛接觸這本書的時候其實不是非常適應(yīng),因為書里面的代碼很多都是不全的,需要結(jié)合網(wǎng)上的一些資料結(jié)合起來學(xué)習(xí)(進(jìn)階書可不是白叫的),比如說View類的四個構(gòu)造方法就沒提,如下圖:
public Zidingyi(Context context) {
this(context, null);
}
public Zidingyi(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public Zidingyi(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public Zidingyi(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
這四個構(gòu)造方法確保了自定義View能夠被大多數(shù)開發(fā)者使用。
原生的TextView使用onDraw()來繪制顯示的文字,代碼如下:
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
所以我們可以認(rèn)為在程序調(diào)用了super.onDraw(canvas)之后,繪制顯示就完成了,那么如果要進(jìn)行自定義View,只能在super.onDraw(canvas)之前進(jìn)行(否則自定義內(nèi)容可能會被顯示的文字重疊覆蓋)。
下面正式開始自定義View。
1.在構(gòu)造方法中完成初始化
mPaint1=new Paint();
mPaint1.setColor(Color.RED);
mPaint1.setStyle(Paint.Style.FILL);
mPaint2=new Paint();
mPaint2.setColor(Color.YELLOW);
mPaint2.setStyle(Paint.Style.FILL);
這里的mPaint1和mPaint2是兩個全局變量,簡單地理解成兩支屬性不同的畫筆?,我們定義了這兩支畫筆的顏色的填充的方式。
2.重寫onDraw()方法
@Override
protected void onDraw(Canvas canvas){
//繪制外層
canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),mPaint1);
//繪制內(nèi)層
canvas.drawRect(10,10,getMeasuredWidth()-10,getMeasuredHeight()-10,mPaint2);
canvas.save();
//繪制前平移10px
canvas.translate(50,0);
//繪制文本
super.onDraw(canvas);
canvas.restore();
這邊解釋一下為什么要在canvas.translate(50,0)之前進(jìn)行canvas.save(),因為canvas.translate()其實是對畫布進(jìn)行操作,這樣能確保繪制完成的內(nèi)外層方框不受畫布移動的影響(經(jīng)過實驗,事實上不加這句話也不會有影響,規(guī)范起見還是加上),這樣相當(dāng)于讓之后繪制的文字向前平移了50個像素。
第一次發(fā)現(xiàn)文字始終顯示不出來弄了半天發(fā)現(xiàn)是一開始錯誤繼承了View類,導(dǎo)致這不是一個TextView。
3.布局文件
<com.example.view.TextViewBack
android:layout_width="300px"
android:layout_height="300px"
android:text="JRs"
android:gravity="center" />
這樣基本的過程就結(jié)束了,下面是效果圖:

接下來會繼續(xù)對其他自定義View的方法和動畫進(jìn)行學(xué)習(xí),謝謝關(guān)注!