效果:父容器是固定的,容器里面的子视图的大小随子视图的数量变化
父容器的大小是确定的,所以不需要记录父容器的大小,子视图的大小是不知道的,所以用measure()方法
首先就需要取得子视图 通过getChildAt(0)可取得子视图
通过分析可得当子视图只有1个是,与子视图有多个时的宽度不一样,并且是不会变的,所以分为两种情况
childCount()可以得到子视图的个数,
//确定空隙
private val space = 30
//因为父容器的宽度与高度在多个地方都会被使用,所以定为全局变量
private var parentWidth =0
private var parentHeight =0
//在onMeasure方法中,测量确定子视图的大小,由于父容器的大小是固定的,所以不需要记录父容器的大小
if (childCount == 1){
val child = getChildAt(0)
val childWidth = parentWidth - 2*space
val childHeight = parentHeight -2*space
val chidWidthSpec = MeasureSpec.makeMeasureSpec(childWidth,MeasureSpec.EXACTLY)
val childHeightSpec = MeasureSpec.makeMeasureSpec(childHeight,MeasureSpec.EXACTLY)
child.measure(chidWidthSpec,childHeightSpec)
}else{
//宽度 宽度是不变的
val childWidth = (parentWidth - 3 * space) / 2
val childWidthSpec = MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY)
var childHeight = 0
var childHeightSpec = 0
if (childCount%2==0){
//高度 高度会随着数量的变化而变化,
childHeight = (parentHeight-(childCount/2+1)*space)/(childCount/2)
childHeightSpec = MeasureSpec.makeMeasureSpec(childHeight,MeasureSpec.EXACTLY)
}else{
childHeight = (parentHeight-((childCount+1)/2+1)*space)/((childCount+1)/2)
childHeightSpec = MeasureSpec.makeMeasureSpec(childHeight,MeasureSpec.EXACTLY)
}
for (i in 0..childCount-1) {
val child = getChildAt(i)
child.measure(childWidthSpec,childHeightSpec)
}
}
在onLayout方法中将子视图布局在父容器中
//记录宽度
var width =space
//记录总高度高度
var allheight = space
//记录每行的高度
var height = 0
for (i in 0..childCount-1){
val child = getChildAt(i)
//判断是否超过了父视图的宽度
if (child.measuredWidth+width>parentWidth){
//超过了
//放在下一行 并且width重置 height增加
width = space
allheight += child.measuredHeight +space
child.layout(width,allheight,width+child.measuredWidth,allheight+child.measuredHeight)
width += child.measuredWidth+space
}else{
//没有超过
//height不变,width增加
child.layout(width,allheight,width+child.measuredWidth,allheight+child.measuredHeight)
width += child.measuredWidth+space
}
}
在xml文件中将自定义的ViewGroup用起来
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.myapplicationviewgroup.myViewGroup
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<View
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark" />
<View
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark" />
<View
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark" />
<View
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark" />
<View
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark" />
<View
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark" />
</com.example.myapplicationviewgroup.myViewGroup>
</androidx.constraintlayout.widget.ConstraintLayout>