自定義ViewGroup,你真正懂了嗎?
背景
自定義View簡單,因為它只需管好自己即可,而自定義ViewGroup不僅僅要管好自己,還要管好子View。接觸過ViewGroup的童鞋應該都清楚,ViewGroup是作為一個View的容器,它裝著子View并將子View放到指定位置上去。
目的
讓大家舉一反三地去自定義定制化的GroupView
思路
自定義GroupView思路
-
首先需要知道子View大小,然后才能確定自定義的GroupView如何設置才能容納它們。
-
根據子View的大小和ViewGroup需要實現的效果,確定最終ViewGroup的大小。
-
ViewGroup和子View的大小確定后,接著就是如何去擺放子View,你可以按照自己特定的規則去擺放。
-
然后將子View對號入座放入已知的分割單元。
實踐
接下來我做一個示例將子View按從左到右順序一個挨著一個擺放,即模仿實現LinearLayout的橫向布局。
首先重寫onMeasure,測量子View大小以及設定ViewGroup最終大小,代碼如下:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 對所有子view進行測量,觸發所有子view的onMeasure函數
measureChildren(widthMeasureSpec, heightMeasureSpec);
// 寬度模式
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
// 測量寬度
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
// 高度模式
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
// 測量高度
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
// 子view數目
int childCount = getChildCount();
if (childCount == 0){
// 如果當前ViewGroup沒有子View,就沒有存在的意義,無需占空間
setMeasuredDimension(0, 0);
}else {
// 如果寬高都是包裹內容
if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST){
// 寬度為所有子view寬度相加,高度取子view最大高度
int width = getTotalWidth();
int height = getMaxHeight();
setMeasuredDimension(width, height);
}else if (widthMode == MeasureSpec.AT_MOST){
// 寬度為所有子View寬度相加,高度為測量高度
setMeasuredDimension(getTotalWidth(), heightSize);
}else if (heightMode == MeasureSpec.AT_MOST){
// 寬度為測量寬度,高度為子view最大高度
setMeasuredDimension(widthSize, getMaxHeight());
}
}
}
/**
* 獲取子view最大高度
* @author leibing
* @createTime 2016/09/19
* @lastModify 2016/09/19
* @param
* @return
*/
private int getMaxHeight() {
// 最大高度
int maxHeight = 0;
// 子view數目
int childCount = getChildCount();
// 遍歷子view拿取最大高度
for (int i=0;i<childCount;i++){
View childView = getChildAt(i);
if (childView.getMeasuredHeight() > maxHeight)
maxHeight = childView.getMeasuredHeight();
}
return maxHeight;
}
/**
* 所有子view寬度相加
* @author leibing
* @createTime 2016/09/19
* @lastModify 2016/09/19
* @param
* @return
*/
private int getTotalWidth() {
// 所有子view寬度之和
int totalWidth = 0;
// 子View數目
int childCount = getChildCount();
// 遍歷所有子view拿取所有子view寬度之和
for (int i=0;i<childCount;i++){
View childView = getChildAt(i);
totalWidth += childView.getMeasuredWidth();
}
return totalWidth;
}</code></pre>
接下來將子View擺放到合適的位置上去,代碼如下:
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// 子view數目
int childCount = getChildCount();
// 記錄當前寬度位置
int currentWidth = l;
// 逐個擺放子view
for (int i = 0;i<childCount;i++){
View childView = getChildAt(i);
int height = childView.getMeasuredHeight();
int width = childView.getMeasuredWidth();
// 擺放子view,參數分別是子view矩形區域的左、上,右,下。
childView.layout(currentWidth, t, currentWidth + width, t + height);
currentWidth += width;
}
}
運行效果圖如下所示:

CustomViewGroup.gif
童鞋們,看完后,自定義ViewGroup是不是很簡單了?
來自:http://www.jianshu.com/p/07ac5921fed8
本文由用戶 LoreneXJE 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!