class FlowViewGroup2(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : ViewGroup(context, attrs, defStyleAttr) {
private val LEFT_MARGIN = 20
private val TOP_MARGIN = 10
private var childViewList: MutableList<MutableList<View>> = ArrayList()
private var oneLineHeightList: MutableList<Int> = ArrayList()
constructor(context: Context) : this(context, null, 0)
constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0)
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
clearViewList()
val widthMeasureSize = MeasureSpec.getSize(widthMeasureSpec)//测量的父控件宽
val heightMeasureSize = MeasureSpec.getSize(heightMeasureSpec)//测量的父控件高
val paddingLeft = paddingLeft
val paddingRight = paddingRight
val paddingTop = paddingTop
val paddingBottom = paddingBottom
var usedParentWidth = 0//已使用的父控件宽
var usedParentHeight = 0//已使用的父控件高
var realParentWidth = 0
var realParentHeight = 0
var oneLineHeight = 0
var oneLineChildViewList: MutableList<View> = ArrayList()
val childCount1 = childCount
for (childIndex in 0 until childCount1) {
val childView = getChildAt(childIndex)
if (childView.visibility != GONE) {
val childLayoutParams = childView.layoutParams
val childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, paddingLeft + paddingRight, childLayoutParams.width)
val childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, paddingTop + paddingBottom, childLayoutParams.height)
childView.measure(childWidthMeasureSpec, childHeightMeasureSpec)
val measuredWidth = childView.measuredWidth
val measuredHeight = childView.measuredHeight
if (usedParentWidth + LEFT_MARGIN + measuredWidth > widthMeasureSize) {
//超过了一屏,切换行吧
childViewList.add(oneLineChildViewList)
oneLineHeightList.add(oneLineHeight)
realParentWidth = Math.max(usedParentWidth, widthMeasureSize)
realParentHeight += TOP_MARGIN + oneLineHeight
//重置,
oneLineChildViewList = ArrayList()
oneLineHeight = 0
usedParentWidth = 0
}
//
usedParentWidth += LEFT_MARGIN + measuredWidth
oneLineChildViewList.add(childView)
oneLineHeight = Math.max(measuredHeight + TOP_MARGIN, oneLineHeight)
//最后一行的高度需要加上
if (childIndex == childCount1 - 1) {
childViewList.add(oneLineChildViewList)
oneLineHeightList.add(oneLineHeight)
realParentWidth = Math.max(usedParentWidth, widthMeasureSize)
realParentHeight += TOP_MARGIN + oneLineHeight
}
}
}
//子控件全部测量完成后,去进行布局吧。
//但是先去获取下父控件的类型
val widthMeasureMode = MeasureSpec.getMode(widthMeasureSpec)
val heightMeasureMode = MeasureSpec.getMode(heightMeasureSpec)
val layoutParentWidth = if (widthMeasureMode == MeasureSpec.EXACTLY) {
widthMeasureSize
} else {
realParentWidth
}
val layoutParentHeight = if (heightMeasureMode == MeasureSpec.EXACTLY) {
heightMeasureSize
} else {
realParentHeight
}
setMeasuredDimension(layoutParentWidth, layoutParentHeight)
}
private fun clearViewList() {
childViewList.clear()
oneLineHeightList.clear()
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
//去遍历
var parentUseLeft = paddingLeft
var parentUseHeight = paddingTop
for (onlineChildViewListIndex in childViewList.indices) {
val childViewList = childViewList[onlineChildViewListIndex]//获取一行的view
val oneLineHeight = oneLineHeightList[onlineChildViewListIndex]//获取这行的高
for (index in childViewList.indices) {
val view = childViewList[index]
val childLeft = parentUseLeft
val childTop = parentUseHeight
val childRight = parentUseLeft + view.measuredWidth
val childBottom = parentUseHeight + view.measuredHeight
view.layout(childLeft, childTop, childRight, childBottom)
parentUseLeft = LEFT_MARGIN + childRight
}
parentUseLeft = paddingLeft
parentUseHeight += oneLineHeight + TOP_MARGIN
}
}
}
网友评论