自定義View關於measure流程的基本思路整理
在《MeasureSpec的簡單說明》這篇文章中對android中View的MeasureSpec測量方法做了詳細的說明,今天這篇博文就Measure的測量做一個簡單的總結。本文著重點在於怎麼將android的一般測量規律應用到自己的自定義View中去,同時也算是給指定一個確定的思路。而對這些測量的內部細節不多做說明。
其實對於Measure要分兩個具體的情況:
1)如果測量的是一個View,那麼通過View這個類帶的measure(int widthMeasureSpec, int heightMeasureSpec)方法就可以完成測量過程。
2)如果是ViewGroup的話,需要先完成childView的測量,這是一個遞迴的過程。根據childView寬和高在做一些其他的處理,比如ListView或者GridView的onMeasure方法。
正如上面所說,view的Measure方法,是呼叫measureint widthMeasureSpec,int heightMeasureSpec),注意裡面的引數,是根據widthSpec/heightSpec來最終確定view的大小的。所說在我們自定義view如果需要測量的話需要先分別獲取view的widthSpec和heightSpec(注:為了描述方便下文widthSpec和heightSpec統統用Spec來表示)。如《MeasureSpec的簡單說明》所說,獲取Spec的方法有兩個
a)呼叫ViewGroup類的getChildMeasureSpec(int spec, int padding, int childDimension) 來獲取View的Spec
.通常來說第一個引數傳遞的是View的parentView的spec。ViewGroupmeasureChild方法可以說是這個方法怎麼使用的參考書,這個方法是ViewGroup用來對childView進行測量的時候呼叫:
protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) { final LayoutParams lp = child.getLayoutParams(); final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec, mPaddingLeft + mPaddingRight, lp.width); final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec, mPaddingTop + mPaddingBottom, lp.height); //執行child的measure流程 child.measure(childWidthMeasureSpec, childHeightMeasureSpec); }
先獲取ViewGroup的Spec即parentSpec,再加上childView的LayoutParams這兩個資訊,然後呼叫getChilMeasureSpec獲取childView的Spec,既然獲取到了Spec了,那麼在呼叫View類的.measure方法把這個Spec交給measure方法處理就是了。
使用案例:ListView對ItemView進行測量的時候獲取ItemView的widthSpec就這麼個思路,具體在measureScrapChild這個方法裡面,相關程式碼如下:
//獲取itemView的LayoutParams
LayoutParams p = (LayoutParams) child.getLayoutParams();
//非空判斷
if (p == null) {
p = (AbsListView.LayoutParams) generateDefaultLayoutParams();
child.setLayoutParams(p);
}
//省略兩行程式碼
//根據父spec+chid的layoutParams
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,
mListPadding.left + mListPadding.right, p.width);
b)通過makeMeasureSpec(int size, int mode)方法來獲取View的Spec值
該方法為ViewGroup類的一個靜態方法,事實上getChildMeasureSpec這個方法最後也就是呼叫了makeMeasureSpec!
使用案例:ListView進行測量的時候獲取ItemView的heightSpec就是這麼個思路,具體在measureScrapChild這個方法裡面,相關程式碼如下:
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
//根據高度和設定的measureSpec來獲取高度spec
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
通過a或者b說的兩個方法獲取到View的Spec值之後就可以呼叫view的measure方法進行view的測量了,具體是使用a還是b,這個倒是根據具體需求具體分析了,沒有固定的要求,可根據需求靈活處理之。ListView關於ItemView的測量完整程式碼如下: private void measureScrapChild(View child, int position, int widthMeasureSpec) {
//獲取itemView的LayoutParams
LayoutParams p = (LayoutParams) child.getLayoutParams();
//非空判斷
if (p == null) {
p = (AbsListView.LayoutParams) generateDefaultLayoutParams();
child.setLayoutParams(p);
}
//省略兩行程式碼
//根據父spec+chid的layoutParams
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,
mListPadding.left + mListPadding.right, p.width);
int lpHeight = p.height;
int childHeightSpec;
if (lpHeight > 0) {
//根據高度和設定的measureSpec來獲取高度spec
childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
} else {
childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
//測量child的寬和個搞
child.measure(childWidthSpec, childHeightSpec);
}
所以上面的對View的測量總的來說其實是很簡單的:第一你只需要先獲取View的Spec值,而且不需要只要具體的Spec得到的內部細節;第二,呼叫View的measure值把
得到的Spec傳給measure方法即可。當然如果需要的話完全可以呼叫setMeasureDimension(int width,int height)來確定一個View的寬和高。具體測量的規則,不同的ViewGroup因為佈局不同有著不同的測量邏輯,但是總的思路上是不會變化的,但是測量基本上會少不了Spec的計算就是了!
最後關於這個measure的靈活應用的使用案例可參考這篇部落格,該篇部落格主要就是運用了measureChildren方法對所有的ChildView進行測量,measureChildren方法其實也就是迴圈呼叫了measureChild方法而已。
相關推薦
自定義View關於measure流程的基本思路整理
在《MeasureSpec的簡單說明》這篇文章中對android中View的MeasureSpec測量方法做了詳細的說明,今天這篇博文就Measure的測量做一個簡單的總結。本文著重點在於怎麼將android的一般測量規律應用到自己的自定義View中去,同時也算是給指定一個確
Pytohn自定義函數基本操作
htm 函數功能 都沒有 proc stat 運算 watermark 傳遞參數 普通 本章包含知識點1、定義函數;2、變量和全局變量區別;3、形參,實參,默認參數;4、多參傳遞,榮譽處理;運行環境 ipython ,交互功能比python清晰,明了。函數介紹函數是編程語言
MySQL自定義函式用法詳解-複合結構自定義變數/流程控制
自定義函式 (user-defined function UDF)就是用一個象ABS() 或 CONCAT()這樣的固有(內建)函式一樣作用的新函式去擴充套件MySQL。 所以UDF是對MySQL功能的一個擴充套件 建立和刪除自定義函式語法: 建立UDF: CREATE 
精通Spring Boot——第十八篇:自定義認證流程
前兩篇簡單介紹了一下使用Spring Security 使用Http Basic登入,以及Spring Security如何自定義登入邏輯。這篇文章主要介紹如何使用handler來定義認證相關的流程。 先做一些自定義的操作,如配置自定義登入頁,配置登入請求URL等。 當我們使用Spring Security時
自定義view流程(結合原始碼分析)
一、View的繪製流程 主要是:測量(measure)、佈局(layout)、繪製(draw)三大流程。 對於一個普通View(不是容器) 主要是關心測量和繪製兩個過程,測量可以確定自身的寬、高、大小,繪製可以顯示出view的具體內容(呈現在螢幕上的)。 對於
Android繪圖系列(二)——自定義View繪製基本圖形
這個系列主要是介紹下Android自定義View和Android繪圖機制,自己能力有限,如果在介紹過程中有什麼錯誤,歡迎指正 前言 在上一篇Android繪圖系列(一)——自定義View基礎中我們瞭解自定義View相關的基本知識,不過,這些東西依舊還
自定義View 篇一--------《自定義View流程分析》
本文部分內容參考自掘金網:點選開啟連結座標圖解:概述Android已經為我們提供了大量的View供我們使用,但是可能有時候這些元件不能滿足我們的需求,這時候就需要自定義控制元件了。自定義控制元件對於初學者總是感覺是一種複雜的技術。因為裡面涉及到的知識點會比較多。但是任何複雜的
如何自己實現一個可自定義業務流程步驟的工作流
專案功能需求簡述 由於業務需要,需要一個申請-審批的工作流,並且業務流程是不固定的,需要能靈活配置,比如現在是:開始->部門經理審批->結束,可能之後就會變為開始->部門經理審批->部門領導審批->結束。因此不能把程式碼寫死,必須
R語言自定義函式及基本分支迴圈結構
使用者自定義函式: 使用者自定義函式名<- function(引數列表){ 計算步驟n Return(函式值) } 分支結構: If(關係表示式){語句} If(關係表示式){語句}else{語句} Ifelse(關係表示式,語句1,語句2) switch(R物件,值
ANDROID自定義檢視——onLayout原始碼 流程 思路詳解
簡介: 在自定義view的時候,其實很簡單,只需要知道3步驟: 1.測量——onMeasure():決定View的大小 2.佈局——onLayout():決定View在ViewGroup中的位置 3.繪製—
PHP整理筆記六自定義函數
php 自定義函數一.標準函數 標準的PHP發行包中有1000多個標準函數,這些標準函數都是系統內置的,不需要用戶自己創建而可以直接使用。<? echo md5(‘123456‘); //MD5函數對字符串進行加密處理?> 二.自定義函數 PHP內置函數允許和文件進
Notification的基本用法以及使用RemoteView實現自定義布局
解決 edi ngs 取消 ets lsp 過程 net tde Notification的作用 Notification是一種全局效果的通知,在系統的通知欄中顯示。既然作為通知,其基本作用有: 顯示接收到短消息、即時信息等 顯示客戶端的推送(廣告、優惠、新聞等)
自定義TempData跨平臺思路
using add 初始化 obj logs temp 模式 既然 [] 一:TempData的自定義實現。。。 TempData是用Session實現的,既然是Session,那模式是線程方式。。。這樣的Session是沒法進行跨平臺的。。。 那麽這就涉及到如何在多臺機器
自定義流程gooflow2.0+自定義表單
log ges bapi cnblogs 語句 參與者 源碼 -1 通過 一、功能簡介 gooflow功能清單1、自定義流程繪制2、自定義屬性添加3、支持3種步驟類型普通審批步驟自動決策步驟手動決策步驟 4、決策方式(支持js決策,sql語句決策) 5、審批人員參與方
VS下WPF自定義控件的基本步驟和基本代碼實現
emp don 謝謝 generic 管理器 參數 bubuko 類的屬性 typeof 一、自定義控件的基本步驟: (本示例項目名稱為:W;添加的自定義控件名稱為) 1、 在“解決方案資源管理器”窗口的項目名上: 右擊à添加à新建項(Ctrl+Shift+A)
自定義View分類與流程
ces ted function ram 註意 measure fin 利用 href 自定義View分類與流程(進階篇)## 轉載出處: http://www.gcssloop.com/customview/CustomViewProcess/ 自定義View繪制流程
div層次整理 / 自定義pycharm補全 / 註釋 /keymap /tab
div css pycharm keymap div css 結構,div套div層次過多。漏個div多個div什麽的,加上結束標記就好排查多了。 在django template裏自定義補全 div層次整理 / 自定義pycharm補全 / 註釋 /keymap /tab
SpringCloud系列五:Ribbon 負載均衡(Ribbon 基本使用、Ribbon 負載均衡、自定義 Ribbon 配置、禁用 Eureka 實現 Ribbon 調用)
control context .mm 別名 void 用戶 size ali ram 1、概念:Ribbon 負載均衡 2、具體內容 現在所有的服務已經通過了 Eureka 進行了註冊,那麽使用 Eureka 註冊的目的是希望所有的服務都統一歸屬到 Eureka 之中進
C# 繪制PDF圖形——基本圖形、自定義圖形、色彩透明度
mat alternate ffi 方法 ref lin 設置 ice pre 引言 在PDF中我們可以通過C#程序代碼來添加非常豐富的元素來呈現我們想要表達的內容,如繪制表格、文字,添加圖形、圖像等等。在本篇文章中,我將介紹如何在PDF中繪制圖形,並設置圖形屬性的操作。
mysql的學習(七)-自定義函數和流程控制
returns spa 會員 返回 類型 mysq -- create decimal DELIMITER // (設置結束符 其實我也不太明白為啥要這樣 記住就行把) CREATE FUNCTION ym_date(mydate DATE) (創建函數