首页/新闻资讯/正文详情

Compose 组件 - 网格布局 Grid

发布时间:2026/9/25 6:11:52 来源:云帆数科 栏目:资讯中心
Compose 组件 - 网格布局 Grid
官方页面一、概念Column/Row 适合一维布局拼出二维布局即便 Compose 不怕嵌套但可读性差。LazyGrid 用于延迟加载大量的同质化条目就好比 ScrollView可滑动的Column 和 RecyclerViewLazyColumn 的区别。Grid 可以在多列或多行布局中显示子元素这些子元素尺寸还可以根据容器大小进行调整。后期改起来灵活性不行子元素多了协调比例会烦死人只在页面正好是个简单的网格比例可以用用属于封装了个细分场景。网格线网格轨道网格由水平和垂直的线条组成边框也是网格线。是两条网格线之间的空间。 行轨道位于两条水平线之间列轨道位于两条垂直线之间。可以在创建网格时定义轨道大小。网格单元网格区域是行轨道和列轨道的交集。由多个网格单元格组成。 可以通过 span 使项跨越多个轨道来定义网格区域。网格间距是网格轨道之间的间距。二、添加依赖[versions] compose 1.11.0-beta02 [libraries] androidx-compose-foundation-layout { group androidx.compose.foundation, name foundation-layout, version.ref compose }三、配置网格容器 Grid(config)Grid()Composableinline fun Grid(noinline config: GridConfigurationScope.() - Unit, //配置容器modifier: Modifier Modifier,content: Composable GridScope.() - Unit, //子元素)Grid( config { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } } ) {}3.1 定义行和列有几个 column() 就有几列按顺序定义不同列的宽度row() 同理。两者调用顺序没有规定可以交替写但影响可读性且无意义。即便不定义也会按照可用空间和固有尺寸进行自动填充和换行。默认填充方向轨道方向是水平一行一行按照列的顺序填充单元格。若 content 中的子元素数量不够填充未被填充的单元格依旧占位。若 content 中的子元素数量超出会新增行由于这行没有被指定单元格高度为该行最高的由于所有列都是已经被指定过的子元素的宽度超出不了。column()添加一列并指定列宽。fun column(size: Dp)固定大小。不推荐这样单元格尺寸不会跟着容器尺寸变化。底层通过 GridTrackSize.Fixed 实现。fun column(percentage: Float)百分比Grid的总可用空间取值范围 0 ~ 1F。底层通过 GridTrackSize.Percentage 实现。fun column(weight: Fr)剩余权重固定大小和百分比之后剩下的空间按权重分配。底层通过 GridTrackSize.Flex 实现。使用示例column(Fr(1F))。fun column(size: GridTrackSize)固有尺寸。参数 GridTrackSize.MaxContent使用内容的最大固有尺寸例如宽度由不换行的文本块中文字的完整长度决定。参数 GridTrackSize.MinContent使用内容的最小固有尺寸例如宽度由文本块中最长的单个字词决定。参数 GridTrackSize.Auto使用可根据可用空间调整的灵活轨道尺寸。默认情况下它的行为与 MaxContent 类似但会缩小并封装其内容以适应父级容器。参数 GridTrackSize.minMax剩余权重 GridTrackSize.Flex 会使用固有尺寸来确定最小尺寸当网格容器没有剩余空间时它会缩到 0dp。为了避免内容无法显示minMax 除了指定剩余权重还额外可强制指定最小尺寸。row()添加一行并指定行高。fun row(size: Dp)fun row(percentage: Float)fun row(weight: Fr)fun row(size: GridTrackSize)Grid( config { //可以交替写但影响可读性且无意义 column(100.dp) //第1列宽100dp column(200.dp) //第2列宽200dp row(100.dp) //第1行高100dp column(300.dp) //第3列宽300dp row(50.dp) //第2行高50dp //一般网格大小相同用 repeat() 添加 repeat(3) { column(200.dp) } repeat(2) { row(100.dp) } } ) {}3.1.1 为剩余权重设置大小限制高度一共就360dp第三行占200dp只剩180dp给其余两个分虽然一二行都设置了权重 1F但是第一行强制指定了最小尺寸因此一二行不是平分各80dp而是第一行100dp第二行60dp。Grid( config { column(1f) row(GridTrackSize.MinMax(100.dp, 1.fr)) row(1.fr) row(200.dp) }, modifier Modifier.size(360.dp) ) { PastelRedCard(MinMax(100.dp, 1.fr)) PastelGreenCard(Flex(1.fr)) PastelBlueCard(Fixed(200.dp)) }3.1.2 将 LazyList 放入剩余权重网格设置剩余权重的轨道会查询子元素的固有尺寸但 Compose 禁止查询 SubcomposeLayoutLazyList 用其实现的固有大小会报错 IllegalStateException。使用 minMax 明确指定最小尺寸解决。Grid( config { column(1f) // 第一行的高度由 Text 可组合项的高度决定。 row(GridTrackSize.Auto) // 第二行占据剩余空间从而使 LazyColumn 能够滚动。 row(GridTrackSize.MinMax(0.dp, 1.fr)) gap(8.dp) }, modifier Modifier.size(width 170.dp, height 240.dp) ) { Text(LazyColumn in a Grid) // LazyColumn 被放置在第二行并填满剩余空间。 LazyColumn(verticalArrangement Arrangement.spacedBy(4.dp)) { items(100) { number - PastelGreenCard(Card $number) } } }3.2 填充方向轨道方向flowvar flow: GridFlowflow GridFlow.Row 默认一行一行按列填充单元格flow GridFlow.Column一列一列按行填充单元格Grid( config { flow GridFlow.Column } }3.3 间距columnGap()fun columnGap(gap: Dp)列间距。rowGap()fun rowGap(gap: Dp)行间距。gap()fun gap(all: Dp)同时设置。Grid( config { gap(8.dp) } }四、配置网格单元 Modifier.gridItem()索引从1开始如果不同时指定 column 和 row 则会将子元素放置在该轨道方向中的下一个可用单元格中。使用正数从轨道起始位置正向填充到索引位置使用负数从轨道结束位置反向填充到索引位置。自动填充的子元素会避开手动指定位置的子元素接着填充。gridItem()fun Modifier.gridItem(AndroidXIntRange(from -MaxGridIndex.toLong(), to MaxGridIndex.toLong())row: Int GridIndexUnspecified, //指定行索引AndroidXIntRange(from -MaxGridIndex.toLong(), to MaxGridIndex.toLong())column: Int GridIndexUnspecified, //指定列索引AndroidXIntRange(from 1) rowSpan: Int 1, //填充几行AndroidXIntRange(from 1) columnSpan: Int 1, //填充几列alignment: Alignment Alignment.TopStart, //元素在网格区域中的对齐方式): Modifier4.1 指定填充位置Grid( config { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } gap(8.dp) } ) { Card1() Card2(modifier Modifier.gridItem(row 2, column 2)) Card3(modifier Modifier.gridItem(row -1, column -2)) }4.2 跨行跨列Grid( config { repeat(3) { column(160.dp) } repeat(3) { row(90.dp) } rowGap(8.dp) columnGap(8.dp) } ) { Card1(modifier Modifier.gridItem(rowSpan 2, columnSpan 2)) Card2() Card3() Card4(modifier Modifier.gridItem(columnSpan 3)) }4.3 网格区域中的对齐方式Grid( config { repeat(3) { column(160.dp) } repeat(3) { row(90.dp) } rowGap(8.dp) columnGap(8.dp) }, ) { Text( text #1, modifier Modifier .gridItem( rowSpan 2, columnSpan 2, alignment Alignment.Center ), ) Card2() Card3() Card4(modifier Modifier.gridItem(columnSpan 3)) }4.4 自动填充与手动指定位置共有6个子元素指定了2和4剩余的 1 3 5 6 按顺序填充未指定的单元格。Grid( config { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } rowGap(16.dp) columnGap(8.dp) } ) { Card1() Card2(modifier Modifier.gridItem(row 2, column 2)) Card3() Card4(modifier Modifier.gridItem(row 3, column 1)) Card5() Card6() }4.5 命名网格区域来填充在网格中放置界面元素时可以使用这些名称而不是坐标索引可读性大大提升。在 config lambda 中使用 GridConfigurationScope 中的 area 函数在网格中注册命名区域。然后您可以使用 gridItem 修饰符和相应的区域标识符将子可组合项分配给这些区域。area 函数将语义标识符例如 enum 类值或字符串键映射到一组物理网格坐标。网格线和索引从 1 开始即第一行为 1第一列为 1。area()fun area(areaId: Any, // 名称row: Int GridIndexUnspecified, // 横坐标column: Int GridIndexUnspecified, // 纵坐标rowSpan: Int 1, // 行跨度columnSpan: Int 1, // 列跨度)enum class GridAreaNames { Area1, Area2, Area3, Area4 }Grid( config { // 定义一个占据所有可用宽度的单列。 repeat(2) { column(0.5f) } // 定义四行每行占总高度的 25%。 repeat(4) { row(0.25f) } // 通过将 areaId 与特定的行和列索引相关联来定义命名网格区域。 // 行和列的索引从 1 开始。 area(areaId GridAreaNames.Area1, row 1, column 1, columnSpan 2) area(areaId GridAreaNames.Area2, row 2, column 1, rowSpan 3) area(areaId GridAreaNames.Area3, rows 2..3, columns 2..2) area(areaId GridAreaNames.Area4, row 4, column 2) gap(4.dp) }, modifier Modifier.size(360.dp) ) { PastelRedCard( Area 1, // 将此可组合项放置到配置块中定义的、具有匹配 ID 的网格区域中。 modifier Modifier.gridItem(areaId GridAreaNames.Area1) ) PastelGreenCard( Area 2, modifier Modifier.gridItem(areaId GridAreaNames.Area2) ) PastelBlueCard( Area 3, modifier Modifier.gridItem(areaId GridAreaNames.Area3) ) PastelYellowCard( Area 4, modifier Modifier.gridItem(areaId GridAreaNames.Area4) ) }

相关推荐

组合式收缩(Compositional Shrinking):Hypothesis 如何通过“收缩输入而非输出“让策略组合保留收缩能力
组合式收缩(Compositional Shrinking):Hypothesis 如何通过“收缩输入而非输出“让策略组合保留收缩能力

测试开发工具 【免费下载链接】hypothesis The property-based testing library for Python 项目地址: https://gitcode.com/gh_mirrors/hy/hypothesis 点击查看 免费下载 导读 本文是 Hypothesis 官方博客"收缩(shrinking)系列"… · 2026/9/25 6:11:52

JUnit 4.8.2 发布说明精读:TestSuite 动态检测 TestCase 与 Warning 测试机制
JUnit 4.8.2 发布说明精读:TestSuite 动态检测 TestCase 与 Warning 测试机制

测试开发工具 【免费下载链接】junit4 A programmer-oriented testing framework for Java — :warning: maintenance mode 项目地址: https://gitcode.com/gh_mirrors/ju/junit4 点击查看 免费下载 本篇基于 JUnit 4 仓库中的 4.8.2 版本发布说明 展开&#xff1a… · 2026/9/25 6:11:52

CorelDRAW下载安装教程:版本选型、高版本转低版本与报错排查
CorelDRAW下载安装教程:版本选型、高版本转低版本与报错排查

1. 为什么矢量设计软件值得你花时间折腾做设计这行十几年,被问得最多的问题不是“怎么做出好看的效果”,而是“我该装哪个版本”“装完打不开怎么办”“客户发来的文件我这边显示乱码”。这些问题里,有一大半都跟矢量设计软件有关。CorelDRAW… · 2026/9/25 6:11:34

ng-zorro-antd Affix(固钉)组件完全指南:从 API 配置到源码级实现原理
ng-zorro-antd Affix(固钉)组件完全指南:从 API 配置到源码级实现原理

UI组件前端 【免费下载链接】ng-zorro-antd Angular UI Component Library based on Ant Design 项目地址: https://gitcode.com/gh_mirrors/ng/ng-zorro-antd 点击查看 免费下载 Affix(固钉)是 ng-zorro-antd 提供的页面固定组件&#xff0… · 2026/9/25 8:51:41

黏菌算法SMA优化SVM/SVR/LSSVM参数:回归预测调参实战
黏菌算法SMA优化SVM/SVR/LSSVM参数:回归预测调参实战

玩SVM的朋友都知道,模型性能的下限靠数据,上限靠调参。尤其做回归预测时,惩罚参数c和核函数参数这两个参数一旦选不好,特征工程做得再漂亮也是白搭。我这边用的方案是黏菌算法SMA去自动搜索SVM、SVR还有LSSVM的惩罚参数c和核函数参… · 2026/9/25 8:51:40

制造经理的高效:从救火队长到系统管理员
制造经理的高效:从救火队长到系统管理员

做了十几年制造经理,我对“高效”这个词越来越警惕。面试的时候老板爱问“你怎么理解效率”,很多人脱口就是“结果导向、执行力强、按计划走”,听着都对,但放到现场基本没用。真正的高效不是你自己一天处理了多少件事,… · 2026/9/25 8:51:40

天津法士特配件总成哪家好 瑞纳铂汽车配件省心之选
天津法士特配件总成哪家好 瑞纳铂汽车配件省心之选

法士特配件总成选购核心逻辑:从原理到落地的避坑指南很多卡友、物流车队管理者在遇到变速箱、离合器总成故障时,最先头疼的就是法士特配件总成怎么选。作为商用车核心传动部件的关键耗材,法士特配件的品质直接决定了车辆出勤率和运维成本&… · 2026/9/25 8:51:16

dnSpy 6.1.3 配 net472:.NET 反编译调试与修改实战指南
dnSpy 6.1.3 配 net472:.NET 反编译调试与修改实战指南

简介:dnSpy-6.1.3-net472.zip 是一款面向 .NET 开发者的反编译与调试工具安装包,基于 .NET Framework 4.7.2 构建,适用于 Windows 平台。它集反编译、调试与代码编辑于一体,可将程序集的 IL 代码还原为 C# 或 VB.NET 源码&#xf… · 2026/9/25 8:51:10

Umi-OCR 离线OCR工具:截图转文字3分钟上手,图片不出本机
Umi-OCR 离线OCR工具:截图转文字3分钟上手,图片不出本机

Umi-OCR 离线OCR工具:截图转文字3分钟上手,图片不出本机 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码… · 2026/9/25 8:51:10

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码