自定義View(一)

<h4>一、初探</h4>
<p>大家都知道自定義view需要重寫onMeasure和onDraw兩個方法,這里我們在講這兩個方法前首先看看什么時候走這兩個方法,這里只是大致講講方便理解,詳細的之后會說。</p>

image.png

看看我在生命周期中加的打印的結果,我們發現onMeasure和onDraw在activity生命周期先走之后在去走,并且onMeasure方法調用了4次,為什么會這樣呢,這屬于深入的內容,以后再講,先記住View的測量和繪制在組件的生命周期之后就行。
</br>
<h4>二、onMeasure和onDraw</h4>
這里簡單講講這兩個方法的用法,先不去探究源碼。
<h6>1、onMeasure</h6>
<p>onMeasure發生在onDraw前,測量的意思,我這里先不說很詳細,網上有些文章說一大堆,什么測量父布局傳遞的寬高什么的,一開始就講這些給初學者我覺得很繞,先會用,在去理解比較好。</p>
<p>(1)先看看onMeasure中傳遞的兩個參數,先記住他們不是寬高。
widthMeasureSpec = 模式+寬;heightMeasureSpec = 模式+高
要獲取到寬高需要這樣寫:</p>
<pre>
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// Log.v("yet","onMeasure");
int heighMode = MeasureSpec.getMode(heightMeasureSpec);
int heigh = MeasureSpec.getSize(heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(width,heigh);
}
</pre>
這樣就是最簡單的,就是說你告訴系統,你要畫出的這個view的寬高,直接為你xml中所寫的寬高。
</br>
<p>(2)模式
上邊說了一個屬性,那么它有什么作用呢?在這里我們加一段switch的代碼,然后去改布局的寬,看看能打印出什么結果。</p>
<pre>
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// Log.v("yet","onMeasure");
int heighMode = MeasureSpec.getMode(heightMeasureSpec);
int heigh = MeasureSpec.getSize(heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);

    switch (widthMode) {
        case MeasureSpec.UNSPECIFIED: {
            Log.v("yet","UNSPECIFIED");
            break;
        }
        case MeasureSpec.AT_MOST: {
            Log.v("yet","AT_MOST");
            break;
        }
        case MeasureSpec.EXACTLY: {
            Log.v("yet","EXACTLY");
            break;
        }
    }
    setMeasuredDimension(width,heigh);
}

</pre>

結果:
<ul>
<li>當布局是match_parent時,打印EXACTLY</li>
<li>當布局是固定尺寸(例如100dp)時,打印EXACTLY</li>
<li>當布局是wrap_content時,打印AT_MOST</li>
</ul>
讓我們來看看結論:

image.png

<h6>其實讀這張表的時候可能剛開始會覺得有點懵逼,不過不要緊,你先記住哪種情況對應哪種模式,之后熟練了,就理解這個表所說的含義了。</h6>
<h6>2、onDraw</h6>
onDraw就是繪制該View,其實這個的知識很多,這篇不詳細去講,也感覺說不完,別人自定義中畫得好的那種都是幾百行代碼。但是雖然內容多,但是套路都一樣,都是弄個畫筆,然后設置畫筆,最后繪畫。
(1)創建畫筆
Paint p = new Paint();
(2)設置畫筆
設置顏色什么之類的,假如paint.setColor(Color.GREEN)將畫筆顏色設置成綠色,當然是選擇原諒她。
(3)畫圖
畫圖的方法也很多,畫圓畫方之類的,這些方法在網上也很容易找到,用起來也簡單,比如畫圓canvas.drawCircle(centerX, centerY, r, paint)。反正每個畫圖一般基本都是:畫布.畫什么(...,畫筆),都是套路。
</br>
<h6>很多朋友第一次接觸或者接觸不多會覺得自定義View很難,這兩個方法里面寫什么看不懂,其實不難,認真看自己動手去做你就會發現自定義View不難,對我來說,我反而覺得比較難的是什么時候系統會調用什么方法和一些條件下的重繪之類的。</h6>
</br>
<h6>總結:這篇主要簡單的講了什么時候走onMeasure和onDraw方法和這兩個方法的簡單用法。</h6>

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容