首页 > 其他分享 >Kotlin实现流式布局

Kotlin实现流式布局

时间:2022-10-20 03:22:05浏览次数:40  
标签:childView val Int Kotlin 布局 流式 rowChips var rowHeight

本篇旨再使用kotlin代码实现TextView的流式排版,采用继承于ViewGroup的形式进行构建。

流式布局采用的方式是由左至右,右上至下的形式。简单的理解就是textview先排满一行后,再排下一行。按照此方式,我们可以确定,每一行应该由一个TextView的集合,同时也应该会确定一个统一的行高:

/**
 * 行视图集合
 */
class FlowChips {
    /**
     * 子视图
     */
     var views: MutiableList<View> = mutableListOf()

    /**
     * 行高
     */
     var rowHeight: Int = 0
}

以下开始实现FlowLayout:

class FlowLayout : ViewGroup {

    private val DEBUG: Boolean = false

    private val TAG: String = "FlowLayout"

    /**
     * 列间隔
     */
    private var mHorizontalSpacing: Int = 10

    /**
     * 行间隔
     */
    private var mVerticalSpacing: Int = 10

    private val chipArray: MutableList<FlowChips> = ArrayList<FlowChips>()

    constructor(context: Context?) : super(context)

    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)

    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    constructor(
        context: Context?,
        attrs: AttributeSet?,
        defStyleAttr: Int,
        defStyleRes: Int
    ) : super(context, attrs, defStyleAttr, defStyleRes)

    @SuppressLint("DrawAllocation")
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        chipArray.clear()
        val selfWidth = MeasureSpec.getSize(widthMeasureSpec)
        val selfHeight = MeasureSpec.getSize(heightMeasureSpec)
        val selfHeightMode = MeasureSpec.getMode(heightMeasureSpec)
        val selfWidthMode = MeasureSpec.getMode(widthMeasureSpec)

        var rowChips = FlowChips()
        var rowHeight: Int = 0;
        var rowWidthUsed: Int = 0;
        var totalHeight: Int = 0;
        for (i in 0 until childCount) {
            val childView = getChildAt(i)
            val lp = childView.layoutParams
            val childWidthMeasureSpec = getChildMeasureSpec(MeasureSpec.makeMeasureSpec(selfWidth, selfWidthMode), childView.paddingStart + childView.paddingEnd, lp.width)
            val childHeightMeasureSpec = getChildMeasureSpec(MeasureSpec.makeMeasureSpec(selfHeight, selfHeightMode), childView.paddingTop + childView.paddingBottom, lp.height)
            childView.measure(childWidthMeasureSpec, childHeightMeasureSpec)

            var rowHeightTemp = rowHeight;
            rowHeightTemp = rowHeightTemp.coerceAtLeast(childView.measuredHeight)
            var widthUsedTemp = rowWidthUsed
            widthUsedTemp += childView.measuredWidth
            if (widthUsedTemp > selfWidth) {
                // 超过父View宽度
                // 此行结束,换行
                totalHeight += rowHeight + mVerticalSpacing;
                chipArray.add(rowChips)

                rowChips = FlowChips()
                rowWidthUsed = childView.measuredWidth
                rowHeight = childView.measuredHeight
                rowChips.rowHeight = rowHeight;
                rowChips.views.add(childView)
            } else {
                rowWidthUsed = widthUsedTemp + mHorizontalSpacing
                rowChips.rowHeight = rowHeightTemp;
                rowChips.views.add(childView)
            }
            if (i == childCount - 1) {
                totalHeight += rowHeight + mVerticalSpacing
                rowChips.rowHeight = rowChips.rowHeight.coerceAtLeast(rowHeight)
                chipArray.add(rowChips)
            }
        }
        setMeasuredDimension(widthMeasureSpec, MeasureSpec.makeMeasureSpec(totalHeight.coerceAtLeast(selfHeight), selfHeightMode))
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        var currentLeft = paddingStart
        var currentTop = paddingTop
        for(chips in chipArray) {
            for(view in chips.views) {
                var start = currentLeft;
                var top = currentTop;
                var end = start + view.measuredWidth
                var bottom = top + view.measuredHeight
                view.layout(start, top, end, bottom)
                currentLeft = end + mHorizontalSpacing
            }
            currentLeft = paddingStart
            currentTop += chips.rowHeight + mVerticalSpacing
        }
    }

}

完结

标签:childView,val,Int,Kotlin,布局,流式,rowChips,var,rowHeight
From: https://www.cnblogs.com/swalka/p/16808381.html

相关文章

  • 表格布局管理器
    表格布局管理器每一个控件都是表格的一个格子,靠操纵这么个格子来管理布局。改成布局管理器<?xmlversion="1.0"encoding="utf-8"?><TableLayoutxmlns:android="http:......
  • Go 项目的文件布局
    转自kcq的https://github.com/golang-standards/project-layouthttps://github.com/golang-standards/project-layout英文版本https://github.com/golang-standards......
  • 铁打的 Kotlin ,从来没让我失望
    作为一个Java开发者,你一定对面向对象编程的核心概念烂熟于胸。Java是纯面向对象语言,如果你想在Java项目中写一个函数,那么你首先得先定义一个类,然后再把函数写到这个类......
  • Qt -- QDockWidget嵌套布局详解-实现Visual Studio布局
    概述许多工程软件,如QtCreator,VS,matlab等,都是使用dock布局窗口,这样用户可以自定义界面,自由组合窗口。Qt的嵌套布局由QDockWidget完成,用QtCreator拖界面得到的dock布置形......
  • 用 Kotlin 的函数式编程 替代 GOF 设计模式
    用Kotlin的函数式编程替代GOF设计模式函数式编程(FP)值就是函数,函数就是值。所有函数都消费函数,所有函数都生产函数。"函数式编程",又称泛函编程,是一种"编程范式"(prog......
  • 【Spring Boot 开发实战】第3讲 Kotlin扩展函数
    幻灯片1.pngSpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。在Java开发领域的诸多著名框架:Spring......
  • 【Spring Boot 开发实战】第2讲 Kotlin类型系统与空安全
    幻灯片1.pngSpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。在Java开发领域的诸多著名框架:Spring......
  • Spring 5.0.3.RELEASE中的 Kotlin 语言等支持
    Spring5.0.3.RELEASE中的Kotlin语言支持​​​1.Kotlin​​​​Kotlin​​​是静态类型语言定位的JVM(以及其他平台),它允许写简洁而优雅的代码,同时提供很好​​的互操作......
  • 使用 Kotlin , Groovy ,Java 开发一个自己的 Gradle 插件
    使用Kotlin,Groovy,Java开发一个自己的Gradle插件先上效果图:image.png功能说明:korGenerate:自动生成Entity,Dao,Controller模板代码korFront:自动cop......
  • 用js调试css 画出所有的css布局
    打开浏览器调试模式,在Console模式下复制下面代码执行[].forEach.call($$("*"),function(a){a.style.outline="1pxsolid#"+(~~(Math.random()*(1<<24))).toString(16)})......