二、自定義垂直ViewGroup如何設定margin
ViewGroup設定margin累計分為三步:
1.獲取margin
2.onMeasure裡面加上margin
3.onLayout佈局設定margin
獲取margin
首先呢,ViewGroup是自帶的MarginLayoutParams的,但是在addView時,檢視原始碼:
public void addView(View child, int index) {
if (child == null) {
throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");
}
LayoutParams params = child.getLayoutParams();
if (params == null) {
params = generateDefaultLayoutParams();
if (params == null) {
throw new IllegalArgumentException(
"generateDefaultLayoutParams() cannot return null");
}
}
addView(child, index, params);
}
然後點開generateDefaultLayoutParams,很明顯,這個generateDefaultLayoutParams是不支援MarginLayoutParams的,但是我們需要獲取到margin值,就需要自己來重寫這個generateDefaultLayoutParams。
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
重寫的generateDefaultLayoutParams,為了相容xml和程式碼new出來addView.這裡我們複寫了所有構造。
public static class VerticalLayoutParams extends MarginLayoutParams {
public VerticalLayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
}
public VerticalLayoutParams(int width, int height) {
super(width, height);
}
public VerticalLayoutParams(LayoutParams lp) {
super(lp);
}
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new VerticalLayoutParams(getContext(), attrs);
}
@Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
return new VerticalLayoutParams(lp);
}
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new VerticalLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
好了,準備工作已經做完了,接下來就可以來計算高度了,首先我們用手動的方式來計算一下總高度:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int totalHeight = 0;
int totalWidth = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
measureChild(child, widthMeasureSpec, heightMeasureSpec);
//計算總共高度
totalHeight = child.getMeasuredHeight() + totalHeight;
ViewGroup.MarginLayoutParams layoutParams = (MarginLayoutParams) child.getLayoutParams();
totalHeight = totalHeight+((ViewGroup.MarginLayoutParams)layoutParams).topMargin;
//取最大的子view的寬度
totalWidth = Math.max(child.getMeasuredWidth(), totalWidth);
}
float xmlMaxWidth = getResources().getDimension(R.dimen.dp250);
float xmlMaxHeight = getResources().getDimension(R.dimen.dp100);
Log.d(TAG,"xmlMaxWidth = "+xmlMaxWidth+" xmlMaxHeight = "+xmlMaxHeight+" totalWidth = "+(totalWidth)+" totalHeight = "+totalHeight);
setMeasuredDimension(totalWidth,totalHeight);
}
執行試驗結果:
線面空出來了一部分黑色。這是因為我們的layout並未將margin這部分實現,那麼接下來就來實現一下吧:
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int curTop = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
VerticalLayoutParams layoutParams = (VerticalLayoutParams) child.getLayoutParams();
curTop = curTop+layoutParams.topMargin;
child.layout(0,curTop,child.getMeasuredWidth(),curTop+child.getMeasuredHeight());
curTop = curTop + child.getMeasuredHeight();
}
}
這短程式碼僅僅增加了:
VerticalLayoutParams layoutParams = (VerticalLayoutParams) child.getLayoutParams();
curTop = curTop+layoutParams.topMargin;
獲取margin並累加,看實驗結果:
已經實現了正常的margin邏輯。
相關文章
- ViewGroup篇:玩一下自定義ViewGroupView
- Android自定義View:ViewGroup(三)AndroidView
- MacBook Pro如何自定義設定快捷鍵?Mac
- 寶塔皮膚如何設定自定義404
- padding 、margin設定百分比的意義padding
- XamarinAndroid元件教程設定自定義子元素動畫(二)NaNAndroid元件動畫
- 自定義流式佈局:ViewGroup的測量與佈局View
- 如何設定 GNOME 顯示自定義幻燈片
- 如何自定義 3/4 層 DDoS 保護設定
- 一篇文章搞懂Android 自定義viewgroup的難點AndroidView
- 如何在Mac上設定自定義鎖屏訊息?Mac
- win10如何自定義主題_win10怎麼設定自定義主題Win10
- 自定義滑鼠設定-中鍵設定為後退
- 垂直margin為什麼會重疊
- 自定義RadiusBackgroundSpan在textview設定tagTextView
- QFileDialog自定義樣式設定SetStytlesheet
- bili-emoji自定義表情包設定
- 介面測試--自定義斷言設定
- rubymine設定自定義快捷程式碼片段
- WRF設定模式垂直層模式
- win10如何自定義解析度 設定win10自定義解析度的具體方法Win10
- 如何在丟失的Mac上設定自定義鎖屏訊息Mac
- win10桌面佈局設定成自定義_windows10桌面圖示如何自定義Win10Windows
- 自定義鍵盤(二)
- 如何修改PbootCMS預設麵包屑導航樣式及自定義設定方法boot
- Android技術分享| 自定義ViewGroup實現直播間大小屏無縫切換AndroidView
- 設定圖片水平垂直居中
- Dynamics CRM 為案例起源設定自定義圖示
- 淺談如何實現自定義的 iterator 之二
- Flutter自定義View(二)—— MultiChildRenderObejctWidgetFlutterView
- Android自定義View:View(二)AndroidView
- UICollectionView自定義佈局(二)UIView
- XamarinAndroid元件教程設定自定義子元素動畫(一)NaNAndroid元件動畫
- keycloak~自定義認證流設定固定redirect_uri
- (五)自定義按鈕模板和設定觸發器觸發器
- Web Components 系列(八)—— 自定義元件的樣式設定Web元件
- 手摸手教你設定部落格園自定義皮膚
- 小程式客服如何設定自定義關鍵詞自動回覆的開發方案。