import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewGroup
import kotlin.math.max
/**
* @author
* @date 4/8/008 9:55
*/
class FlowLayout @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ViewGroup(context, attrs, defStyleAttr) {
//所有行
private val lines = mutableListOf<Line>()
//当前行
private var line: Line? = null
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
"onMeasure".log()
//实际可用大小
val width = MeasureSpec.getSize(widthMeasureSpec) - paddingLeft - paddingRight
val height = MeasureSpec.getSize(heightMeasureSpec) - paddingTop - paddingBottom
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
val heightMode = MeasureSpec.getMode(heightMeasureSpec)
lines.clear()
line = null
for (i in 0 until childCount) {
val child = getChildAt(i)
//测量所有child
measureChild(child, widthMeasureSpec, heightMeasureSpec)
if (line == null) {
newLine()
}
//当前view需要的宽度
val measuredWidth = child.measuredWidth
if (line!!.children.isEmpty()) {
line!!.addChild(child)
} else {
if (line!!.width + measuredWidth > width) {
//放不下了
newLine()
}
line!!.addChild(child)
}
}
var totalHeight = paddingTop + paddingBottom
lines.forEach { totalHeight += it.height }
"totalHeight = $totalHeight".log()
setMeasuredDimension(
MeasureSpec.getSize(widthMeasureSpec),
resolveSize(totalHeight, heightMeasureSpec)
)
}
private fun newLine() {
"newLine".log()
line = Line()
lines.add(line!!)
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
var top = paddingTop
lines.forEach {
"lines.count = ${lines.size}".log()
it.layout(paddingLeft, top )
top += it.height
}
}
inner class Line {
val children = mutableListOf<View>()
var height = 0
var width = 0
fun addChild(child: View) {
children.add(child)
height = max(height, child.measuredHeight)
width += child.measuredWidth
}
fun layout(left: Int, top: Int) {
var currentLeft = left
for (child in children) {
"childrenCount = ${children.size}, l = $currentLeft, t = $top, r = ${currentLeft + child.measuredWidth}, b = ${top + child.measuredHeight}".log()
child.layout(
currentLeft,
top,
currentLeft + child.measuredWidth,
top + child.measuredHeight
)
currentLeft += child.measuredWidth
}
}
}
}
fun Any?.log() {
Log.d("dxl", this?.toString() ?: "----null")
}
网友评论