软件编程
位置:首页>> 软件编程>> Android编程>> Android自定义ViewGroup多行多列效果

Android自定义ViewGroup多行多列效果

作者:卖炭少年炭治郎  发布时间:2022-10-31 06:07:17 

标签:Android,多行多列

本文实例为大家分享了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
       }
   }
}

来源:https://blog.csdn.net/weixin_38687303/article/details/120011073

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com