Android自定义ViewGroup多行多列效果

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

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

标签:Android,多行多列
0
投稿

猜你喜欢

  • Spring+SpringMVC+MyBatis深入学习及搭建(三)之MyBatis全局配置文件解析

    2022-03-21 05:25:23
  • JAVA的LIST接口的REMOVE重载方法调用原理解析

    2021-07-20 16:35:27
  • SpringCloud基本Rest微服务工程搭建过程

    2023-08-28 16:23:29
  • Android中post请求传递json数据给服务端的实例

    2022-04-21 01:51:18
  • Java中包装类和Arrays类的详细介绍

    2023-12-03 22:04:13
  • C#通过反射打开相应窗体方法分享

    2023-09-21 07:37:14
  • Java中BigDecimal类的add()的使用详解

    2023-03-07 16:12:11
  • java数据结构与算法之快速排序详解

    2023-02-23 10:23:43
  • java简单实现斗地主发牌功能

    2023-06-18 16:22:44
  • 详解关于SpringBoot的外部化配置使用记录

    2023-08-10 03:54:54
  • idea前后跳转箭头的快捷键

    2022-09-08 10:55:44
  • 2022最新Java泛型详解(360度无死角介绍)

    2022-03-08 15:13:42
  • Java持久化框架Hibernate与Mybatis优劣及选择详解

    2023-12-03 19:46:14
  • Java设计模式之命令模式(Command模式)介绍

    2021-12-02 01:01:02
  • Android支付宝支付设计开发

    2022-11-19 18:05:25
  • Android在linux下刷机教程

    2023-09-03 17:21:04
  • Java 电话号码的组合示例详解

    2023-07-30 22:27:53
  • 解决线程池中ThreadGroup的坑

    2023-08-24 00:13:47
  • C#使用随机数编写班级点名器的示例代码

    2022-05-26 11:04:51
  • 最最常用的 100 个 Java类分享

    2023-08-21 08:45:05
  • asp之家 软件编程 m.aspxhome.com