Android - 流式布局(代码)
发布日期:2021-05-08 16:16:01 浏览次数:15 分类:精选文章

本文共 3872 字,大约阅读时间需要 12 分钟。

流式布局的实现(Kotlin语言)

import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isEmpty
class FlowLayout : ViewGroup {
constructor(context: Context): super(context) {}
constructor(context: Context, attrs: AttributeSet?): super(context, attrs) {}
private val space = 30
var allViews: MutableList
= mutableListOf()
var everyLineViews: MutableList
= mutableListOf()
private var allLineHeightList: MutableList
= mutableListOf()
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
var maxWidth = 0
var parentHeight = 0
var parentWidth = 0
var currentWidth = space
var currentHeight = space
var totalHeight = 0
allViews.clear()
everyLineViews.clear()
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val parentMaxWidth = MeasureSpec.getSize(widthMeasureSpec)
Log.v("zj", "父容器最大宽度:$parentMaxWidth")
for (i in 0 until childCount) {
val child = getChildAt(i)
val lp = child.layoutParams
val childWidthSpec = getChildMeasureSpec(
widthMeasureSpec,
2 * space,
lp.width
)
val childHeightSpec = getChildMeasureSpec(
heightMeasureSpec,
2 * space,
lp.height
)
child.measure(childWidthSpec, childHeightSpec)
if (currentWidth + space + child.measuredWidth <= parentMaxWidth) {
currentWidth += child.measuredWidth + space
currentHeight = Math.max(currentHeight, child.measuredHeight + space)
} else {
allViews.add(everyLineViews)
everyLineViews = mutableListOf()
totalHeight += currentHeight
allLineHeightList.add(currentHeight)
maxWidth = Math.max(maxWidth, currentWidth)
currentHeight = child.measuredHeight + space
currentWidth = child.measuredWidth + space
}
everyLineViews.add(child)
}
if (!everyLineViews.isEmpty()) {
currentWidth = 0
currentHeight = 0
for (i in 0 until everyLineViews.size) {
val child = everyLineViews[i]
currentWidth += child.measuredWidth + space
currentHeight = Math.max(currentHeight, child.measuredHeight + space)
}
maxWidth = Math.max(maxWidth, currentWidth)
totalHeight += currentHeight
allLineHeightList.add(currentHeight)
allViews.add(everyLineViews)
}
parentHeight = totalHeight + space
parentWidth = maxWidth + space
setMeasuredDimension(parentWidth, parentHeight)
}
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
var left = space
var top = space
var right = 0
var bottom = 0
for (i in 0 until allViews.size) {
for (j in 0 until allViews[i].size) {
val child = allViews[i][j]
right = left + child.measuredWidth
bottom = top + child.measuredHeight
child.layout(left, top, right, bottom)
left += child.measuredWidth + space
}
top += allLineHeightList[i]
left = space
}
}
}

代码解释

该代码实现了一个自定义的流式布局View类,主要功能包括:

  1. 定义控件之间的间隔(space)
  2. 保存所有子控件的布局信息
  3. 按行布局子控件,自动换行
  4. 计算每行的高度和总体的布局参数

代码中的关键逻辑包括:

  1. 测量子控件的宽度和高度
  2. 判断是否需要换行
  3. 记录每行的布局信息
  4. 设置父容器的最终尺寸

注:代码中使用了测量布局(Layout Measurement)和布局(Layout)过程的标准方法,确保了布局的准确性和兼容性。

上一篇:Android - 动画
下一篇:Java中使用字符流读取UTF-8和写出txt文件 乱码 问题

发表评论

最新留言

初次前来,多多关照!
[***.217.46.12]2025年05月13日 17时48分36秒