欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Android自定义ViewGroup多行多列效果

程序员文章站 2022-04-09 11:44:07
本文实例为大家分享了android自定义viewgroup多行多列的具体代码,供大家参考,具体内容如下先看下效果图每行两个子孩子每行一个子孩子实现思路自定义viewgroup,实现测量和布局,使控件适...

本文实例为大家分享了android自定义viewgroup多行多列的具体代码,供大家参考,具体内容如下

先看下效果图

每行两个子孩子

Android自定义ViewGroup多行多列效果

每行一个子孩子

Android自定义ViewGroup多行多列效果

实现思路

自定义viewgroup,实现测量和布局,使控件适应业务场景。

测量

根据父控件的宽度,平均分给每个子孩子固定的宽度。高度就是行数乘以一个子孩子的高度,再加上空隙的高度。

根据子孩子个数计算行数  

val rows = if (childcount % perlinechild == 0) {
            childcount / perlinechild
        } else {
            childcount / perlinechild + 1
        }

代码示例

override fun onmeasure(widthmeasurespec: int, heightmeasurespec: int) {
        val width = measurespec.getsize(widthmeasurespec)
        for (i in 0 until childcount) {
            val child: view = getchildat(i)
            if (child.visibility != gone) {
                val lp = child.layoutparams
                val childwidthmeasurespec = getchildmeasurespec(
                    widthmeasurespec,
                    0, (width - (perlinechild - 1) * space) / perlinechild
                )
                val childheightmeasurespec = getchildmeasurespec(
                    heightmeasurespec,
                    0, lp.height
                )
                child.measure(childwidthmeasurespec, childheightmeasurespec)
            }
        }
        val rows = if (childcount % perlinechild == 0) {
            childcount / perlinechild
        } else {
            childcount / perlinechild + 1
        }
        if (childcount > 0) {
            setmeasureddimension(
                width,
                getchildat(0).measuredheight * rows + (rows - 1) * space
            )
        }
    }

布局

需要注意摆放的顺序和位置,每行摆放固定的个数,达到个数之后换行继续摆放

代码示例 

override fun onlayout(changed: boolean, l: int, t: int, r: int, b: int) {
        var left = l
        var top = t
        children.foreachindexed { index, view ->
            if (index % perlinechild == 0) {
                left = 0
                if (index != 0) {
                    top += view.measuredheight
                    top+=space
                }
                view.layout(left, top, view.measuredwidth + left, top + view.measuredheight)
            } else {
                view.layout(left, top, view.measuredwidth + left, top + view.measuredheight)
            }
            left += view.measuredwidth
            left += space
        }
    }

完整代码

class multilineviewg @jvmoverloads constructor(
    context: context, attrs: attributeset? = null, defstyleattr: int = 0
) : viewgroup(context, attrs, defstyleattr) {

    var perlinechild = 2

    /**
     * 子孩子之间的空隙
     */
    var space = 10

    override fun onmeasure(widthmeasurespec: int, heightmeasurespec: int) {
        val width = measurespec.getsize(widthmeasurespec)
        for (i in 0 until childcount) {
            val child: view = getchildat(i)
            if (child.visibility != gone) {
                val lp = child.layoutparams
                val childwidthmeasurespec = getchildmeasurespec(
                    widthmeasurespec,
                    0, (width - (perlinechild - 1) * space) / perlinechild
                )
                val childheightmeasurespec = getchildmeasurespec(
                    heightmeasurespec,
                    0, lp.height
                )
                child.measure(childwidthmeasurespec, childheightmeasurespec)
            }
        }
        val rows = if (childcount % perlinechild == 0) {
            childcount / perlinechild
        } else {
            childcount / perlinechild + 1
        }
        if (childcount > 0) {
            setmeasureddimension(
                width,
                getchildat(0).measuredheight * rows + (rows - 1) * space
            )
        }
    }

    override fun onlayout(changed: boolean, l: int, t: int, r: int, b: int) {
        var left = l
        var top = t
        children.foreachindexed { index, view ->
            if (index % perlinechild == 0) {
                left = 0
                if (index != 0) {
                    top += view.measuredheight
                    top+=space
                }
                view.layout(left, top, view.measuredwidth + left, top + view.measuredheight)
            } else {
                view.layout(left, top, view.measuredwidth + left, top + view.measuredheight)
            }
            left += view.measuredwidth
            left += space
        }
    }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。