<?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();
}
}
}
![学习安卓小码哥自定义控件的笔记(四) 学习安卓小码哥自定义控件的笔记(四)](/default/index/img?u=aHR0cHM6Ly9waWFuc2hlbi5jb20vaW1hZ2VzLzkzNS9iZDJmZTVlOWMzYzRlZGY2N2EyM2IzODdhMjBkYzYyNy5wbmc=)