<?xml version="1.0" encoding="utf-8"?>
<com.example.wtz.verticallayoutview.VerticallayoutView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark"
tools:context=".MainActivity">
<View
android:layout_width="100dp"
android:layout_height="50dp"
android:background="#f00"/>
<View
android:layout_width="150dp"
android:layout_height="50dp"
android:background="#0f0"/>
<View
android:layout_width="120dp"
android:layout_height="50dp"
android:background="#00f"/>
</com.example.wtz.verticallayoutview.VerticallayoutView>
package com.example.wtz.verticallayoutview;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
public class VerticallayoutView extends ViewGroup {
public VerticallayoutView(Context context) {
super(context);
}
public VerticallayoutView(Context context, AttributeSet attrs) {
super(context, attrs);
}
//onMeasure
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//如果是wrap_content,寬應該是多大? 寬應該是子控件中最大的那個寬度
//如果是wrap_content,高應該是多大? 高應該是所有子控件的高度之和
//提前去測量一個子控件,不然待會拿不到子控件的尺寸
measureChildren(widthMeasureSpec, heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int childWidthMax = getChildWidthMax();
int childHeightSum = getChildHeightSum();
switch (widthMode) {
case MeasureSpec.AT_MOST:
widthSize = childWidthMax;
heightSize = childHeightSum;
break;
case MeasureSpec.EXACTLY:
break;
}
setMeasuredDimension(widthSize, heightSize);
}
//獲得所有子控件的高度之和
private int getChildHeightSum() {
int childCount = getChildCount();
int sumHeight = 0;
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
int measuredHeight = childView.getMeasuredHeight();
sumHeight += measuredHeight;
}
Log.d(getClass().getSimpleName(), "getChildHeightSum: sumHeight" + sumHeight);
return sumHeight;
}
//獲得是子控件中最大的那個寬度
private int getChildWidthMax() {
int childCount = getChildCount();
int maxWidth = 0;
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
//直接通過getWidth是拿不到寬度的
// int width = childView.getWidth();
//寫自定義控件時,要通過getMeasuredWidth來拿寬度的
//有個前提,需要先去測量一下這個子控件,你才能拿得到
int width = childView.getMeasuredWidth();
Log.d(getClass().getSimpleName(), "getChildWidthMax: width :" + width);
if (maxWidth < width) {
maxWidth = width;
}
}
return maxWidth;
}
//設定子控件的排列
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
//将子控件們布局到合适的位置
//周遊子控件,調用子控件的layout方法,去布局到合适的位置
int childCount = getChildCount();
int top = 0;
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
//假如是第一個子控件
childView.layout(0, top, childView.getMeasuredWidth(), top + childView.getMeasuredHeight());
top += childView.getMeasuredHeight();
}
}
}