看完這篇還不會自定義 View ,我跪搓衣板

2022-07-04 13:39:13 字數 2900 閱讀 1584

在實際使用的過程中,我們經常會接到這樣一些需求,比如環形計步器,柱狀圖表,圓形頭像等等,這時我們通常的思路是去google 一下,看看 github 上是否有我們需要的這些控制項,但是如果網上收不到這樣的控制項呢?這時我們經常需要自定義 view 來滿足需求。

關於自定義控制項,一般輝遵循一下幾個套路

方法是用來重新測量,並設定控制項的大小,我們知道控制項的大小是用 width 和 height 兩個標籤來設定的。通常有三種賦值情況 :

這時也許你就會有疑問,既然都已經有了這些屬性,那還重寫 onmeasure 幹嘛,直接呼叫 view 的方法不就行了嗎?但是你想想,比如你設計了乙個圓形控制項,使用者在 width 和 height 都設定了 wrap_parent 屬性,同時又給你傳了一張長方形的,那結果會怎麼樣?必然得讓你「方」啊。。所以這時就需要重寫 onmeasure 方法,設定其寬高相等。

首先把 onmeasure() 打出來

@override

protected void onmeasure(int widthmeasurespec, int heightmeasurespec)

這時大家不眠會好奇,明明是重繪大小,那麼給我提供寬高就行了呀?這個 int widthmeasurespec, int heightmeasurespec ,是個什麼鬼?其實很好理解,大家都知道計算機中資料是已二進位制儲存的。同時,就像我之前講的 view 的大小賦值形式有三種,那麼在計算機中,要儲存二進位制數,需要幾位二進位制呢,答案很明了 -> 兩位。同時大家也發現,這兩個引數都是 int 型的。int 型資料在計算機中用 30為儲存。所以聰明的 google 就把這 30 位劃分為兩部分。第一部分兩位拿來存型別,後面 28 位拿來存資料大小。

首先,無論是 width 還是 height ,我們都得先判斷型別,再去計算大小,so~ 咱先寫個方法專門用於計算並返回大小。

測量模式

表示意思

unspecified

父容器沒有對當前view有任何限制,當前view可以任意取尺寸

exactly

當前的尺寸就是當前view應該取的尺寸

at_most

當前尺寸是當前view能取的最大尺寸

private int getmysize(int defaultsize, int measurespec) 

case measurespec.at_most:

case measurespec.exactly:

}return mysize;

}

然後,我們再從 onmeasure() 中呼叫它

@override

protected void onmeasure(int widthmeasurespec, int heightmeasurespec) else

// 設定大小

setmeasureddimension(width, height);

}

在 xml 中應用試試效果

<?xml version="1.0" encoding="utf-8"?>

到這裡圖就已經重繪出來了,讓我們執行一下下

我們驚呆了,說好的控制項呢??! 別急,咱還沒給他上色呢,所以它自然是透明的。所以現在重寫 ondraw() 方法,在 ondraw() 方法中

我們通過 canvas (安卓的乙個繪圖類物件進行圖形的繪製)

@override

protected void ondraw(canvas canvas)

大功告成!但是善於思考的可能會發現:使用這種方式,我們只能使用父類控制項的屬性,但是我們有時需要更多的功能,比如:控制項需要改變透明度,卡片控制項需要設定陰影值等等,那麼父類控制項的屬性顯然不夠用了,這時我們就要開始實現自定義布局。

由於自定義布局屬性一般只需要對 ondraw() 進行操作。所以 onmeasure() 等方法的重寫我就不再囉嗦了,這裡我打算繼承字 view 實現乙個類似 textview 的控制項。

首先,讓我們現在 res/values/styles 檔案中增加乙個自定義布局屬性。

@color/colorprimary

@color/colorprimarydark

@color/coloraccent

這些標籤都是什麼意思呢?

首先:myview 是自定義布局屬性的名字,也就是標籤也就是入口,在 ondraw 中,用 context.obtainstyledattributes(attrs, r.styleable.myview); 獲得自定義布局屬性的全部子項。

其次:attr 中的 name 便是你屬性的名字,比如說這個 text_size 、text_color 、text_text  這三個屬性,在 布局檔案中就是:

最後:

format 標籤,format 標籤指定的是資料型別,具體可以看這篇,我在這裡就不重複了 ->

上面我們先定義了屬性,又在布局中對其賦值,那麼實際中,我們如何在自定義控制項裡,獲得它的實際值呢?讓我們先寫下構造方法,在構造方法中獲得這些值的大小:

private int textsize;

private string texttext;

private int textcolor;

public myview(context context)

public myview(context context, attributeset attrs)

由於在構造方法中,我們已經獲得基本的值,所以在 ondraw() 中,將這些東西繪製出來就行了,這裡直接上**:

@override

protected void ondraw(canvas canvas)

Android自定義View 自定義元件

自繪控制項也分兩種,自定義元件和自定義容器,自定義元件是繼承view類,自定義容器時繼承viewgrounp 今天主要分析下自定義元件 還是舉個例子來的實際些,假如我們要畫乙個最簡單的textview,首先想到的就是canvas.drawtext 方法,怎麼畫了?還是得一步一步來 1 寫乙個myte...

自定義view之自定義屬性

1.首先在res的values檔案下新建乙個名為attrs.xml檔案 在該xml檔案中編寫我們需要的屬性 declare styleable後面的name必須要與接下來要自定義的view名一致。attr 後面的name表示需要自定義的屬性,format表示這些屬性的型別 2.新建乙個類繼承text...

自定義view 二

自定義view的最重要的乙個部分是自定義它的外觀。根據你的程式的需求,通過ondraw方法實現繪製。在ondraw中,會傳遞給你乙個canvas。canvas封裝了繪製圖形的方法。還需要自定義乙個 paint去定義顏色樣式的填充 簡單來說 canvas定義你在螢幕上畫的圖形,而paint定義顏色,樣...