1 Star 0 Fork 0

xiaow / AndroidPractiseCode

Create your Gitee Account
Explore and code with more than 6 million developers,Free private repositories !:)
Sign up
Clone or download
FlowLayout.kt 3.51 KB
Copy Edit Web IDE Raw Blame History
xiaowu authored 2021-01-11 17:27 . add.
package com.github.jxiaow.sample.flowlayout
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import com.github.jxiaow.sample.R
/**
* 流式布局
*
* 利用流式布局来完成对自定义布局measure 和 layout的使用
* {@sample R.layout.layout_flow_example}
*/
class FlowLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ViewGroup(context, attrs, defStyleAttr) {
private var isOnce = true
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
if (!isOnce) {
return
}
// 测量自身大小
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
// 获取测量的值
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
val widthSize = MeasureSpec.getSize(widthMeasureSpec)
val heightMode = MeasureSpec.getMode(heightMeasureSpec)
val heightSize = MeasureSpec.getSize(heightMeasureSpec)
val flowWidth = widthSize
var flowHeight = 0
var currentWidth = 0
var currentHeight = 0
// 用来标志行结束view
var lastChild: View? = null
// 遍历child 进行测量
for (index in 0 until childCount) {
// 获取child
val child = getChildAt(index)
measureChild(child, widthMeasureSpec, heightMeasureSpec)
// 获取param
val lp = child.layoutParams as MarginLayoutParams
val childWidth = child.measuredWidth + lp.leftMargin + lp.rightMargin
val childHeight = child.measuredHeight + lp.topMargin + lp.bottomMargin
if (currentWidth + childWidth > widthSize) {
lastChild?.setTag(R.string.flow_row_tag, currentHeight)
flowHeight += currentHeight
currentHeight = childHeight
currentWidth = childWidth
lastChild = null
} else {
lastChild = child
currentHeight = currentHeight.coerceAtLeast(childHeight)
currentWidth += childWidth
}
if (index == childCount - 1) {
lastChild?.setTag(R.string.flow_row_tag, currentHeight)
flowHeight += currentHeight
}
}
if (heightMode == MeasureSpec.EXACTLY) {
flowHeight = heightSize
}
// 保存测量结果
setMeasuredDimension(flowWidth, flowHeight)
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
var left = 0
var top = 0
var right = 0
var bottom = 0
var curLeft = 0
var curTop = 0
for (index in 0 until childCount) {
val child = getChildAt(index)
val lp = child.layoutParams as MarginLayoutParams
left = curLeft + lp.leftMargin
top = curTop + lp.topMargin
right = left + child.measuredWidth
bottom = top + child.measuredHeight
child.layout(left, top, right, bottom)
val tag = child.getTag(R.string.flow_row_tag)
if (tag is Int) {
curLeft = 0
curTop += tag
} else {
curLeft += lp.leftMargin + child.measuredWidth + lp.rightMargin
}
}
isOnce = false
}
override fun generateLayoutParams(attrs: AttributeSet?): LayoutParams {
return MarginLayoutParams(context, attrs)
}
}

Comment ( 0 )

Sign in for post a comment

Android
1
https://gitee.com/jxiaow/practiseCodeAndroid.git
git@gitee.com:jxiaow/practiseCodeAndroid.git
jxiaow
practiseCodeAndroid
AndroidPractiseCode
master

Search