尧图精选

NativeScript GridLayout 布局完全指南:从 XML 声明到程序化构建与源码级原理

🕒 发布时间:2026/10/1 10:24:37 📁 来源:尧图网络
【免费下载链接】NativeScript⚡ Write Native with TypeScript ✨ Best of all worlds (TypeScript, Swift, Objective C, Kotlin, Java, Dart). Use what you love ❤️ Angular, React, Solid, Svelte, Vue with: iOS (UIKit, SwiftUI), Android (View, Jetpack Compose), Flutter and you name it compatible.项目地址https://gitcode.com/gh_mirrors/na/NativeScript点击查看免费下载本指南以仓库文档 apps/automated/src/ui/layouts/grid-layout.md 为骨架结合 NativeScript 核心布局源码与自动化测试系统讲解 GridLayout 的声明方式、columns/rows语法、子视图的col/row/colSpan/rowSpan放置规则以及通过ItemSpec程序化构建网格的完整方法并深入解析其底层实现机制。GridLayout 是什么GridLayout 是 NativeScript 中最灵活、最常用的布局容器之一。它将可用空间划分成行rows与列columns组成的二维网格每个子视图通过行列索引定位到具体单元格并可通过跨行rowSpan与跨列colSpan实现跨单元格合并非常适合构建表格、表单、仪表盘等复杂界面。在 NativeScript 中使用 GridLayout 需要先引入 GridLayout 模块同时通常还会用到ItemSpec行/列规格对象来定义网格的每一行每一列的尺寸策略。本指南将分别覆盖XML 声明式用法与TypeScript 程序化用法两种方式。模块引入与基础声明引入 GridLayout 模块使用 GridLayout 需要导入nativescript/core中的 GridLayout 模块。在自动化测试中对应的代码片段如下见 grid-layout-tests.tsimport { GridLayout, ItemSpec } from nativescript/core/ui/layouts/grid-layout; import { Button } from nativescript/core/ui/button; const gridLayout new GridLayout();也可以在 XML 中直接使用GridLayout标签无需显式 import——XML 模板解析器会自动注册该组件。在 XML 中声明 GridLayout原文档给出了最经典的声明示例通过columns与rows两个属性以逗号分隔的方式一次性定义网格结构GridLayout columns80, *, auto rowsauto, * Button col0 / Button col1 / Button col2 / !-- 默认情况下 column 和 row 都为 0 -- Button row1 colSpan3 / /GridLayout上述声明等价于3 列第 1 列固定 80 像素80第 2 列占据剩余空间*第 3 列按内容自适应auto2 行第 1 行按内容自适应auto第 2 行占据剩余空间*前三个按钮分别放在第 0、1、2 列的第 0 行第四个按钮放在第 1 行并通过colSpan3横跨全部三列。行/列取值语法详解由 grid-layout-common.ts 中的convertGridLength解析逻辑确认写法含义对应 GridUnitType内部表示80或100固定像素宽度/高度pixel绝对尺寸ItemSpec(80, pixel)*占据剩余空间默认权重 1star星号弹性ItemSpec(1, star)10*按权重 10 分配剩余空间starItemSpec(10, star)auto根据子视图内容自适应auto自动ItemSpec(1, auto)解析器对空白并不敏感parseAndAddItemSpecs使用正则/[\s,]/分割因此逗号与空格甚至混合都可以作为分隔符。自动化测试 test_set_columns_in_XML_comma_separator 与 test_set_columns_in_XML_space_separator 分别验证了columnsauto, *, 10*, 100 与columnsauto * 10* 100 两种写法解析结果完全一致即 auto 列、权重 1 的 star 列、权重 10 的 star 列和 100 像素的绝对列。子视图放置col、row、colSpan、rowSpan每个加入 GridLayout 的子视图都带有四个与网格定位相关的属性col列、row行、colSpan跨列数、rowSpan跨行数。其默认值由源码在 grid-layout-common.ts 中定义View.prototype.row 0; View.prototype.col 0; View.prototype.rowSpan 1; View.prototype.colSpan 1;也就是说默认放在第 0 行第 0 列不跨行不跨列。这些默认行为同样被测试用例 test_row_defaultValue 等逐一断言row默认 0、col默认 0、rowSpan默认 1、colSpan默认 1。此外源码为View.prototype定义了column与columnSpan作为col与colSpan的同义词属性见 grid-layout-common.ts二者读写互通。测试 test_synonym_property_setting_column_changes_col 系列验证了设置column会影响col、设置columnSpan会影响colSpan。因此XML 中使用col或column均可。添加子视图程序化构建时先用addChild把视图加入网格再设置定位属性。原文档对应的代码片段见 grid-layout-tests.tsconst btn1 new Button(); const btn2 new Button(); const btn3 new Button(); const btn4 new Button(); gridLayout.addChild(btn1); gridLayout.addChild(btn2); gridLayout.addChild(btn3); gridLayout.addChild(btn4);设置 column将 btn1、btn2、btn3 分别放入第 0、1、2 列使用静态方法GridLayout.setColumn(view, value)设置视图所在列见 grid-layout-tests.tsGridLayout.setColumn(btn1, 0); GridLayout.setColumn(btn2, 1); GridLayout.setColumn(btn3, 2);设置 row将 btn4 放到第 1 行使用静态方法GridLayout.setRow(view, value)见 grid-layout-tests.tsGridLayout.setRow(btn4, 1);设置 columnSpan让 btn4 横跨所有列使用静态方法GridLayout.setColumnSpan(view, value)见 grid-layout-tests.tsGridLayout.setColumnSpan(btn4, 3);同理跨行使用GridLayout.setRowSpan(view, value)。这些静态方法均有对应的 gettergetColumn、getRow、getColumnSpan、getRowSpan并且统一通过validateArgs校验入参——传入null或undefined会抛出异常而负数值或 0 值则被允许不抛出相关行为由 grid-layout-tests.ts 中的多组测试覆盖。这些 setter 的实现非常轻量本质是直接写子视图原型上的col/row/colSpan/rowSpan属性见 grid-layout-common.ts。除了「先 addChild 再 setXxx」两步式GridLayout还提供了addChildAtCell(view, row, column, rowSpan?, columnSpan?)一步完成「加入并定位」测试见 test_addChildAtCell_with_all_params省略的可选参数默认取 1不跨行/列。程序化构建网格ItemSpec 与 addRow / addColumn当网格结构需要在运行时动态确定时可以用ItemSpec描述每一行/列再通过addColumn/addRow添加到网格中。创建 ItemSpec3 列80px、、auto 2 行auto、原文档给出的完整示例见 grid-layout-tests.ts// ItemSpec 的 mode 对列而言指的是列宽 // 绝对尺寸列 const firstColumn new ItemSpec(80, pixel); // Star 宽度该列会扩展以填满其他列留下的剩余空间 const secondColumn new ItemSpec(1, star); // Auto 尺寸该列会扩展或收缩以便为所有子 UI 元素提供足够空间 const thirdColumn new ItemSpec(1, auto); // Star 和 Auto 模式对行而言行为与列相同只不过作用对象是行高 const firstRow new ItemSpec(1, auto); const secondRow new ItemSpec(1, star);ItemSpec构造函数的两个参数是(value: number, type: string)type 只接受三种取值pixel绝对、star星号弹性、auto自适应。从 grid-layout-common.ts 的实现可以看到不传参数时默认value 1、类型为star传两个参数时要求value为非负数、非 NaN、非 Infinity 的数字类型必须是合法字符串否则抛出异常非法类型如unsupported会被GridUnitType.parse拒绝测试 test_ItemSpec_constructor_throws_onWrongType 对此有断言。ItemSpec还暴露了三个只读布尔属性用于判断类型isAbsolutepixel、isAutoauto、isStarstar以及gridUnitType、value、actualLength布局后该行/列的实际像素长度默认 0见 test_ItemSpec_actualLength_defaultValue。把列和行添加到 GridLayout创建好 ItemSpec 之后调用addColumn/addRow依次加入见 grid-layout-tests.tsgridLayout.addColumn(firstColumn); gridLayout.addColumn(secondColumn); gridLayout.addColumn(thirdColumn); gridLayout.addRow(firstRow); gridLayout.addRow(secondRow);对应地还有addColumns(...)/addRows(...)批量、removeColumn/removeRow单个移除、removeColumns()/removeRows()全部清空与getColumns()/getRows()读取当前行/列规格数组。需要特别注意的是同一个ItemSpec一旦被加入某个 GridLayout 就不能重复使用——源码validateItemSpec会检查itemSpec.owner已归属其他网格的规格对象会被拒绝见 grid-layout-common.ts。清空与移除行为分别由测试 test_removeColumns 验证。三种尺寸模式的行为差异源码实测搞清楚pixel/star/auto三种模式在测量与布局阶段的差异是写出稳定 UI 的关键。自动化测试 test_columnsActualWidth_isCorrect 与 test_rowsActualHeight_isCorrect 给出了一个 4×4 网格1*、2*、50px、auto在 300×300 容器中的实测结果pixel绝对行/列严格按设定值测量与布局不随内容变化star星号按权重比例瓜分「扣除绝对列与 auto 列之后」的剩余空间。例如 4 个权重均为 1 的 star 列在 110px 宽度下会被均分为约 28/27/28/27 px见 test_ColumnWidth_when_4stars_and_width_110而1*与2*两列则按 1:2 分配各 50px 与 100pxauto自动以该行/列内所有子视图的测量尺寸为基准收缩或扩展。测试中给 auto 列里的按钮设置 100px 宽auto 列最终实际宽度即为 100px。测量与布局的对应关系见 test_Measure_and_Layout_Children_withCorrect_size可总结为模式测量measure布局layoutpixel子视图按规格值测量子视图按规格值布局可能被拉伸star子视图按规格值测量子视图按精确分配长度布局auto子视图按自身内容测量子视图按其测量尺寸布局actualLength属性保存的就是布局完成后每一行/列的真实像素长度可在getRows()[i].actualLength/getColumns()[i].actualLength上读取是运行时检查布局结果的常用手段。更多实用能力addChildAtCell 一步定位grid.addChildAtCell(btn, row, column, rowSpan, columnSpan)将「添加 定位 跨行列」合并为一次调用适合动态生成网格内容的场景。XML 属性绑定rows/columns属性同样支持通过数据绑定动态赋值解析器已做字符串化处理以兼容绑定值见 grid-layout-common.ts 中parseAndAddItemSpecs对非字符串值的处理。与百分比支持协同GridLayout 与 NativeScript 布局系统整体的百分比尺寸支持保持一致测试 test_percent_support_nativeLayoutParams_are_correct 复用了公共布局测试套件进行验证。原生视图回收GridLayout 及其子项均通过原生视图回收测试test_recycling可在 ListView 等复用场景中安全使用。总结GridLayout 是 NativeScript 中掌控二维布局的核心容器XML 中通过columns80, *, auto这类简洁语法快速声明网格子视图用col/row/colSpan/rowSpan精准定位运行时则用ItemSpecaddColumn/addRow动态构建任意行列结构。理解pixel固定、star按权重瓜分剩余空间、auto随内容自适应三种尺寸模式的测量与布局差异并结合actualLength校验实际结果即可在表单、仪表盘等复杂界面中稳定、高效地使用 GridLayout。如需继续深入可阅读原文档apps/automated/src/ui/layouts/grid-layout.md完整测试用例apps/automated/src/ui/layouts/grid-layout-tests.ts核心实现packages/core/ui/layouts/grid-layout/grid-layout-common.ts公共布局测试apps/automated/src/ui/layouts/common-layout-tests.ts赞分享【免费下载链接】NativeScript⚡ Write Native with TypeScript ✨ Best of all worlds (TypeScript, Swift, Objective C, Kotlin, Java, Dart). Use what you love ❤️ Angular, React, Solid, Svelte, Vue with: iOS (UIKit, SwiftUI), Android (View, Jetpack Compose), Flutter and you name it compatible.项目地址https://gitcode.com/gh_mirrors/na/NativeScript点击查看免费下载相关推荐NativeScript ListView 全指南从声明式 XML 到原生虚拟化列表的完整实践NativeScript ListView 全指南从声明式 XML 到原生虚拟化列表的完整实践 ListView 是 NativeScript 框架中用于展示NativeScript WebView 完整实战指南从 XML 声明到加载远程 URL、本地文件与原始 HTMLNativeScript WebView 完整实战指南从 XML 声明到加载远程 URL、本地文件与原始 HTML WebView 是 NativeScripFresh 框架程序化布局app.layout完整指南从基础用法到源码级原理Fresh 框架程序化布局app.layout完整指南从基础用法到源码级原理 本篇技术指南围绕 Fresh 框架的 程序化布局programmatic后端前端上一篇eslint-plugin-unicorn 快照测试解读no-xor-as-exponentiation 规则如何拦截误把位异或当乘方的写法下一篇CANN PyPTO fillpad 接口详解不改形状的常量填充算子实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →