十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

拆解Grid 网格布局实战:原生鸿蒙页面的实现路径与调试方法

拆解Grid 网格布局实战:原生鸿蒙页面的实现路径与调试方法 Grid 网格布局实战从一页三种排布读懂 ArkUI 的状态与栅格这张页面实际完成了什么这张页面的功能很集中顶部有“固定列数”“自适应”“混合网格”三个可点击的文字标签标签决定中间显示哪一种内容每种内容中都有一批数字卡片点到普通数字卡片时卡片会变为深色底部提示会显示刚刚选中的数字。第三种内容还有一个橙色的“焦点内容”大卡点它会把底部提示改成 99。它没有网络请求、登录、路由跳转、数据库、搜索、排序和分页。数据不是从接口拿到的而是由几个数字数组直接提供给ForEach。这样做不是为了模拟完整业务而是为了把 Grid 最基础的排布、循环和选择状态放在一张容易观察的页面里。初学 Grid 时如果同时加上图片加载、接口异常和复杂卡片很容易看不清“列模板到底控制了什么”。页面只保留两个 number 状态界面变化因此能直接对应到具体操作。应用启动后标题区域显示“网格布局”和副标题“固定列数 · 自适应 · 混合网格”右侧有一个“008”标记。mode的初始值为 0所以默认打开“固定列数”分支。白色内容卡内展示“三列固定网格”以及 1 到 9 的九个数字。点顶部标签时页头、标签栏和底部提示仍留在原位只有中间白色内容卡换成另一种结构这不是跳转到新页面而是根据 mode 进行条件构建。首图展示了页面的浅灰蓝底色、白色圆角内容卡、三列默认网格、奇数紫色卡片、偶数蓝色卡片以及底部浅蓝提示。它记录的是手机上的一次运行结果不代表所有设备尺寸都采用了响应式列数方案。后面会区分页面文案中的“自适应”和实际呈现的列数。页面容器与内容范围进入页面后直接看到这张网格练习页。页面没有第二个业务页也没有在点击事件内执行路由跳转所以任何格子都不能被理解为导航入口。根节点是Scroll它的宽和高都是100%背景色为#F5F7FB。Scroll 内部放入Column({ space: 14 })Column 也全宽并有 18 的内边距。标题行、模式栏、当前模式的内容卡、底部提示都属于这个纵向 Column。Grid 只是其中局部的一部分而不是整个页面的根容器。这层关系决定了页面首先按从上到下的方式摆放区块然后在某些区块内部按网格摆放项目。外层使用 Scroll不等于每个网格项目都有懒加载。当前九个、八个或四个小项目数量非常少页面只是在整页外围提供一个垂直滚动容器。较矮设备、较大字体或内容更长时Scroll 能让用户继续向下查看页面没有引入 LazyForEach、列表虚拟化或按可视区域创建项目。将“能够滚动”与“数据懒加载”分开是读这类示例时最容易漏掉的边界之一。页面有两份响应式状态。mode决定当前内容分支0 是三列固定网格1 是标题为“自适应卡片”的四列网格2 是混合内容。selected表示当前选中的数字-1 代表初始时未选择。状态的粒度很小也没有多余对象观察一个点击动作时只要判断它写的是 mode 还是 selected就能知道它会影响模式还是选择效果。两份状态彼此不会自动重置。顶部三段标签只更新 mode普通格子只更新 selected焦点内容把 selected 设为 99。比如在固定三列模式点过 7 后再切换模式selected 仍是 7。第二种模式恰好也包含 7所以它会直接以深色显示第三种模式只包含 10 到 13小格不会出现深色但底部仍会报告 7。这是当前交互自然形成的结果而不是存在某种隐藏同步。顶部三项标签怎样由 mode 控制标题行是全宽的Row。左侧为Column({ space: 4 })包含 24 字号、粗体、颜色#172033的“网格布局”以及 13 字号、颜色#667085的副标题。这个 Column 使用alignItems(HorizontalAlign.Start)对齐文字并通过layoutWeight(1)占据标题行的剩余宽度。右侧的小编号标签是 13 字号蓝色文字背景为#EAF1FF内边距 10、圆角 12。页面没有给标题区画分隔线或投影视觉层次来自字号、颜色、两端布局和页面留白。标签栏是另一个Row({ space: 8 })。里面的三个 Text 按同样的方式设置layoutWeight(1)、居中文字、10 的内边距与 10 的圆角因此会在同一行平分可用空间。它们不是 Button事件直接写在 Text 的onClick上。页面也没有独立按钮组件、禁用态或键盘导航逻辑。第一项“固定列数”的颜色条件是this.mode 0 ? Color.White : #667085背景条件是this.mode 0 ? #2563EB : #F1F5F9。第二、三项把比较值改成 1、2。点击事件没有直接操纵某个 Text 的样式它只更新 mode重新构建时每个标签依据同一状态重新计算白字蓝底还是灰字浅底。默认 mode 为 0所以首屏第一项被突出。点“混合网格”后第三项被突出内容分支也随之切换。这种写法展示了声明式 UI 最实用的一点回调写“状态是什么”构建代码写“状态为某值时界面像什么”。本页不需要分别寻找三个标签然后手动还原颜色。对于三项、样式高度一致的练习页三段显式 Text 很容易核对。如果以后标签数量、文案、图标、权限和禁用条件显著增加再把标签抽成数据结构或组件是另一件事当前工程并没有那一层抽象。默认分支九项如何排成固定三列mode 0时页面创建一个白色圆角的 Column。该卡片设置width(100%)、padding(16)、backgroundColor(Color.White)、borderRadius(18)内部space为 10。第一项是 18 字号粗体、全宽的标题“三列固定网格”第二项才是 Grid。卡片的 16 内边距决定网格与白卡边缘的距离而卡片内标题和 Grid 的空隙来自 Column 的space: 10。Grid 内部使用ForEach([1,2,3,4,5,6,7,8,9],(item:number){GridItem(){this.Cell(item,item%20?#2563EB:#7C3AED)}})数组是固定的 1 到 9页面没有增删该数组的事件。ForEach 每次迭代创建一个 GridItemGridItem 是 Grid 的直接项目GridItem 内再调用 Cell 生成真正可见的数字卡。不要把 GridItem 和 Cell 当成同一个概念前者参与网格轨道排版后者定义文字、背景、圆角和点击行为。正因为 Text 放在 GridItem 内Grid 才能按项目而非按一堆普通文字来安排位置。布局的关键是.columnsTemplate(1fr 1fr 1fr).rowsGap(10).columnsGap(10).width(100%)三个同权重的1fr表示三个等分列轨道。Grid 先在全宽可用区域内扣除两个 10 的列间距再把剩余横向空间按三份分配。数据依序填入故第一行是 1、2、3第二行是 4、5、6第三行是 7、8、9。columnsGap(10)只控制相邻列之间的距离rowsGap(10)只控制相邻行之间的距离它们不同于外层 Column 的 space后者控制标题到 Grid 的垂直距离。这里的“固定三列”准确指列数固定为 3并不表示单元格横向尺寸固定。Grid 的宽度随父容器变化三个轨道也随之变宽或变窄但列数仍是三。普通 Cell 把宽度写为100%、高度写为 92所以它横向填满自己的 GridItem纵向高度固定。页面没有rowsTemplate行由九个按顺序出现的项目自然形成。理解这一点后就不会把“固定列”误解为“固定正方形卡片”。奇偶配色发生在调用 Cell 的地方item % 2 0的偶数得到蓝色#2563EB奇数得到紫色#7C3AED。因此未选中时 1、3、5、7、9 是紫色2、4、6、8 是蓝色。这个规则只属于默认网格第二个网格和混合网格会传入完全不同的常态色。Cell 不负责判断奇偶它只接收一个颜色参数并在必要时覆盖为选中色。Cell一个共享 selected 的可复用数字格数字格被抽成可复用的 Builder。它接收数字与常态背景色再构造一个 Text数字以字符串显示字号为 25字重是 Bold字色为白色文本横向居中宽度为 100%高度为 92顶部内边距为 28圆角为 14。截图里数字处在卡片中部附近是这一组字号、高度和顶部 padding 的综合效果页面没有使用额外的垂直居中容器。这个 Builder 的核心规则是当前 selected 与卡片数字相等时使用深色背景否则使用传入的常态色点击卡片时把 selected 更新为该数字。点击某个普通格selected 会被赋为该格的数字。页面重新按状态计算背景时只有相等的卡片走深色#172033其余格子继续使用各自的常态色。比如点 44 从蓝色变深色再点 74 恢复蓝色7 变深色。页面没有逐个把其他格子“取消”一份单值状态已经表达了当前只选一个项目。重复点同一个数字不会取消选择。两次点击都把 selected 设为相同值背景和底部提示不变。初始 -1 只在页面初始时代表“无选择”页面没有“若已选中则回到 -1”的判断也没有单独的重置按钮。因此它不是多选或可取消选择控件。这个 Builder 读取页面共享的 selected本身没有独立状态也没有声明自己的属性。所有普通格子都使用同一份选择结果调用时只需提供自己的编号和颜色。Builder 适合复用这种结构、样式与点击行为都相同的小片段。混合模式的焦点内容与普通格不同它是文字“焦点内容”、高度 140、圆角 18、橙色背景点击写入 99因此页面单独构建了 Text而没有勉强复用 Cell。这说明复用的边界应由真实结构决定不是所有彩色块都必须走同一个 Builder。第二种模式名称是“自适应”代码是固定四列点“自适应”后mode 变为 1第一段内容不再构建第二段白色卡片出现。它同样有 16 的内边距和 18 的圆角标题为“自适应卡片”。数组是[0,1,2,3,4,5,6,7]每项都调用this.Cell(item, #0F766E)所以未选中状态的八张卡一律为深青绿。截图中可见两行四列第一行 0、1、2、3第二行 4、5、6、7。这里要以页面实际模板为准这个模式并没有真正按屏幕宽度自动增减列数而是使用四条等分轨道。和默认模式相比变化只是从三个等分轨道变成四个不是通过宽度阈值在三列、四列、五列之间做选择。因此“自适应”是页面中的标签与标题文案不能被描述为已实现的响应式列数算法。更窄的设备上页面不会自动切回三列四个轨道仍在每格横向更窄。更宽的设备上也不会自动增加为五列。等分单位的作用只是让已确定的四个轨道共同平分当前可用宽度。若未来要做到真正的自适应需要新增尺寸判断或另一套模板策略这不是当前页面已经拥有的功能。第二种模式还帮助理解数值 0。selected 初始为 -1所以首次进入时 0 并未被选中点 0 后selected 变为 0this.selected value对 0 成立底部的this.selected 0也成立于是 0 变深色且提示显示“已选中网格项0”。这里没有依赖“数值是否为真”的判断因此不能因为 0 在某些语言环境常被当作假值就误判它无法被选择。选择状态跨模式共享会产生两种不同现象。若在默认模式点 3再切到第二种模式第二种模式里的 3 也会立即变深色因为可见 Cell 的 value 同样是 3。若点的是 9第二种模式没有 9于是没有任何深色普通格但底部仍会显示 9。这个现象说明 selected 是整页的一份数字并不是某个 Grid 自己维护的局部索引。混合内容全宽焦点块加一个两列 Grid当 mode 为 2 时条件语句进入最后的else。该分支的卡片先放 18 字号标题“混合内容网格”再放 14 字号、灰色#667085的说明文字“大卡用于突出内容小卡用于快速入口。”接着出现一个全宽 Text“焦点内容”。它是 22 字号粗体白字高度 140内边距 18背景为橙色#EA580C圆角为 18点击时执行this.selected 99。说明文字中的“小卡用于快速入口”只是在表达布局意图并不能说明工程已经实现导航。小格的点击仍只会改 selected不会进入任何页面。焦点内容也不会打开详情它同样只写入一个数字。保持这层边界读者就能把视觉演示和已实现的业务行为分开。焦点内容不是 GridItem也没有使用跨列、跨行属性。它作为外层 Column 的直接孩子通过全宽设置形成横向大块其后才创建一个 Grid。当前页面没有跨列声明。因此它确实展示了“大块配小块”的视觉组合但没有演示跨列 GridItem。两种实现可能看起来相似组件层级却不同。小 Grid 对[10,11,12,13]做 ForEach每一项仍是 GridItem 内调用 Cell常态色传#F59E0B。它的模板为1fr 1fr行列间距均为 10故四项排成两行两列。普通 Cell 的高度、圆角、文字样式和选中规则在这里完全复用。点 12 时12 变为#172033底部显示 12。点橙色焦点内容则会把 selected 设为 99。底部条件满足显示“已选中网格项99”但焦点内容自己的背景是固定的#EA580C没有读取 selected因此仍保持橙色四个小格也没有 value 99故不会有任何小格变深。这是现有代码明确产生的交互结果。不能笼统写成“所有可点内容都会变为选中深色”因为焦点内容是例外。这个分支内部的Column({ space: 10 })负责标题、说明、大卡和小 Grid 之间的垂直空隙外层页面 Column 的space: 14负责整张内容卡与底部提示之间的空隙小 Grid 自己的rowsGap、columnsGap负责格与格之间的空隙。调布局时可以沿这三层排查不要把白卡的 padding、Column 的 space 和 Grid 的 gap 误认为同一个参数造成。底部提示与一次点击的数据流三个模式分支之后页面始终保留一段浅蓝提示文字。selected 小于零时显示“点击任意网格项查看选择状态”选中数字后显示“已选中网格项”和对应数字。它处在条件内容之外所以无论当前显示三列、四列还是混合内容都存在。初始 selected 为 -1文字是引导语点任何普通数字后显示相应编号点焦点内容后显示 99。提示不记录数据来自哪种模式也不是自动消失的 Toast。它只是页面里一直可见的一段文字依赖 selected 重新计算内容。以默认模式点 6 为例可以把声明式更新具体化。触摸命中 6 对应的数字卡后selected 从 -1 变成 6所有可见数字卡重新判断6 变为#172033其他数字恢复或保持各自的常态色底部提示拼出“已选中网格项6”。页面没有查询组件标识也没有直接命令提示区改字而是由状态变化带动界面更新。切换“自适应”时的数据流不同回调仅写 mode 为 1。标签栏中三个比较 mode 的样式一起更新第二项变蓝条件渲染改为第二张内容卡底部提示不读取 mode因此保持 selected 的结果。把“谁写哪一份状态”和“谁读取哪一份状态”列清楚是理解本页所有交互的简单办法。组件职责、尺寸与颜色逐项核对Grid、GridItem、ForEach 与 Cell 分工并不重叠。Grid 定义列模板、行列间隙和布局区域GridItem 是参与该网格排版的直接孩子ForEach 依次为数组元素重复创建 GridItemCell 决定数字内容、常态色、选择覆盖色和点击赋值。短数组直接放进 ForEach对当前展示练习来说足够直观。它没有 key 策略、动态插入删除或服务端数据同步因此也不应被描述成已处理复杂动态列表。普通格的高度统一为 92而三列、四列、两列模板的单列宽度不同。于是三种模式并不是等比例缩放四列中的格子明显更窄两列中更宽但它们一样高。这不是截图偶然而是“横向由模板和父宽分配、纵向由 Cell 常量决定”的结果。GridItem 没有设置 margin白卡边缘到格子的距离来自卡片padding(16)格子之间来自 gap。页面颜色也可逐项定位。整体背景是#F5F7FB主标题与普通格选中态是#172033蓝色#2563EB用在选中模式、底部提示文字和默认网格偶数常态副标题、说明和未选中模式文字是#667085未选中模式背景是#F1F5F9编号标签和提示区背景是#EAF1FF。默认奇数格是#7C3AED第二种网格是#0F766E焦点内容是#EA580C混合模式小格是#F59E0B。普通格一旦选中都会由深色覆盖传入色焦点内容除外。字号层级是主标题 24、焦点内容 22、卡片标题 18、数字 25、模式文字与底部提示 14、副标题和编号 13。圆角则是普通数字格 14、模式标签 10、提示与编号标签 12、内容卡与焦点内容 18。页面没有阴影、边框、渐变、动态主题或字体设置截图中的卡片层次主要来自白底与浅色背景的对比、圆角和留白。把视觉效果对应回具体属性比用“高级卡片风格”一类笼统描述更方便复现和调试。在 DevEco Studio 中逐项观察在 DevEco Studio 中运行页面即可无需准备账号、接口或本地数据。首先不点击任何元素检查首屏应有浅灰蓝背景、左侧标题、右侧编号、三个模式标签第一项蓝底白字白卡标题为“三列固定网格”九项按三列三行排布奇数紫色、偶数蓝色底部为“点击任意网格项查看选择状态”。如果启动即有深色格应检查初始选择值是否仍为 -1。然后点默认模式的 6。应只有 6 变深色提示显示 6。接着点 7应看到深色从 6 转到 7其他格保持奇偶常态色重复点 7状态不会取消。这个测试同时验证 Cell 的点击回调、背景条件和底部文字读取的是同一 selected。第三步点“自适应”。第二段标签应变为蓝底白字白卡标题变为“自适应卡片”内容是 0 到 7 的两行四列未选中时皆为#0F766E。若之前选了 7切换后 7 会立即深色若之前选 9则底部仍显示 9 而这八格没有深色。点 0 后0 应深色且提示显示 0。该步骤特别能验证“固定四列”这一页面事实。第四步点“混合网格”。应看到标题、灰色说明、橙色焦点内容和下面两列的 10 到 13。点 1212 变深色并显示 12点焦点内容提示显示 99橙色大卡不变色小格也不出现 99 的深色。这样可验证它是独立全宽 Text 加小 Grid而不是一个跨列项目。最后可换一个不同宽度或旋转设备观察。应预期三种模板分别仍为三列、四列、两列外层页面在需要时可以滚动不应预期第二种模式自动变列也不应把 Scroll 当成大列表优化。明确的实现边界当前页面没有真正的响应式列数第二种模板固定为四个等分轨道。它没有跨列或跨行 GridItem焦点内容在 Grid 外面。它没有 LazyForEach、懒加载、分页、缓存、网络请求、加载失败处理、数据持久化、账号、搜索、排序、筛选、路由或详情页。三组数据都是短小的固定数组所有点击只修改页面内的 mode 或 selected。它也没有多选、取消选择、选择来源记录或模式切换时自动清空选择。焦点内容没有跟随 selected 改色普通格才有统一深色选中逻辑。当前页面主要面向手机尺寸不能把这个示例称为已经验证平板、折叠屏或多端自适配。这些限制不是缺点清单而是本页学习边界它适合练习等分列、GridItem、ForEach、Builder 和状态驱动样式而不是用来证明复杂业务能力。小结这个页面的三种排版都能直接追到一行列模板默认是1fr 1fr 1fr第二种实际是四个1fr混合模式的小 Grid 是两个1fr。大焦点块来自外层 Column 的全宽 Text不是跨列网格。普通数字格通过 GridItem 与 ForEach 进入布局通过Builder Cell统一样式与点击规则。从交互角度看模式标签只写 mode普通格和焦点内容只写 selected模式标签样式与条件分支读 mode普通格深色与底部提示读 selected。用这条线索读完页面就能区分哪些现象来自 Grid 轨道哪些来自状态比较哪些只是视觉文案。以后在自己的 ArkTS 页面里增加真正的自适应列数、跨列项目或大数据列表时也应将这些能力作为新增设计明确实现而不要把它们想象成这个练习页已经具备的默认行为。从可用宽度推演三种网格的差别理解列模板时最容易只记住“写三个等分轨道就是三列”却没有把它和父容器宽度、内边距、间隙放在一起考虑。本页恰好提供了三种列数因此可以在不修改页面的前提下做一次尺寸推演。设外层内容区域在某台设备上有一段可用宽度页面 Column 先在两侧各留出 18 的 padding白色内容卡又在两侧各留出 16 的 padding。Grid 的width(100%)只能取得卡片内部的横向区域而不是整块屏幕宽度。三列 Grid 接着扣掉两段列间距每段都是 10剩余的部分才由三个等权轨道平分。这意味着当读者觉得“三列格子为什么没有贴近屏幕边缘”时应该先从布局层级向内推而不是先怀疑 Grid 算错屏幕边缘到页面内容有一层 18内容到白卡内部又有一层 16白卡内部相邻格子之间还有 10。第二种四列模式在同样的父宽中需要扣掉三段 10 的列间距然后把余量分给四列它的单格自然比三列模式窄。混合模式的小 Grid 只需要扣一段 10再把余量二分因此单个小格显得更宽。所有这些变化都无需改变数字格的宽度设置因为它会跟着自己所在的 GridItem 宽度填满。纵向方向则是另一套规则。每个普通 Cell 明确写了height(92)所以无论当前有三列、四列还是两列普通格高都保持 92。默认模式有三行行间两个rowsGap(10)第二种有两行行间一段 10混合模式的小 Grid 也有两行。标题到 Grid 之间由卡片 Column 的space: 10留开而白卡上下又由padding(16)留出缓冲。因而白卡总高度不是“数字个数乘以 92”这么简单还要加上行间距、标题高度、卡片内的纵向间距和内边距。只要能把这些层次分开遇到卡片高度不如预期时就能定位该看height、rowsGap、space还是padding。这也解释了为什么本页的“固定列数”在窄屏上并不会自动换行成更多行。列轨道的数目在模板里已经写死Grid 不会依据数字宽度替你选择另一套模板。三个1fr始终是三条轨道四个1fr始终是四条轨道。对于当前展示用的单个数字即便列变窄通常仍能显示若以后把数字换成长标题、加入图标或增加最小触摸区域原有四列可能不再合适。那时需要明确决定新的布局规则例如在不同可用宽度下采用不同列模板或调整卡片内容不能把责任交给这份静态模板而期待它自动完成。从 GridItem 的角度看当前页面也没有人为指定任何一项的起始行、起始列或占据范围。项目完全按 ForEach 的先后顺序流入 Grid先来的项目放在前面的空格随后项目继续填充。默认数组是递增的所以视觉编号也是从左到右、从上到下递增这并不是 Grid 对数字进行了排序而是数组本来就按这个顺序提供。如果把数组顺序改成其他顺序网格位置会跟着数组顺序变化。这个区分在以后排查“为什么 5 出现在第一行”时很重要先检查数据顺序再检查列模板不要默认 Grid 会按数值大小重排。同样GridItem在本页没有设置独立背景、圆角、高度或点击事件。可见的彩色形状来自它里面的 Text也就是数字格。若只看屏幕容易认为每个 GridItem 本身是一张色卡应当知道 GridItem 的主要作用是作为网格项目的结构节点。这样的划分让布局责任与外观责任分离想改变列数时看 Grid想改变每项外观时看数字格想改变某项数据时看 ForEach 数组。对初学者来说这种分层比记住一串修饰器更可靠。mode 与 selected 的状态矩阵本页的两个状态虽少却足以形成一些值得实际验证的组合。mode决定“当前页面可见哪些 value”selected 决定“其中哪一个 value 可能获得深色背景”。可见集合分别是mode 为 0 时的 1 到 9mode 为 1 时的 0 到 7mode 为 2 时的普通格 10 到 13再加一个并不走 Cell 背景逻辑的焦点值 99。只要一个已保存的 selected 出现在当前可见普通格集合中相等比较就会令对应普通格变深否则普通格没有深色但底部文本仍会保留这个数字。例如初始组合是 mode 为 0、selected 为 -1显示三列所有格常态底部为引导语。点 4 后组合变为 0、4三列仍在4 深色底部报 4。切到 mode 为 1 后组合是 1、4四列出现其中 4 仍深色因为新分支也有 value 为 4 的 Cell。切到 mode 为 2 后组合是 2、4混合内容出现但小格只从 10 开始因此没有普通格满足比较提示却仍显示 4。这样的状态迁移不需要阅读框架内部机制只要按两个变量的赋值和各分支数组就能手工推导。再看焦点内容的特殊组合。点击它之后是 mode 为 2、selected 为 99。底部明确显示 99因为它只要求 selected 大于等于 0小格 10、11、12、13 都与 99 不相等所以没有深色焦点内容背景也不会变深因为它根本没有this.selected 99这样的条件。随后切到 mode 为 0 或 1底部仍报 99两个普通网格中也不会出现深色。这不是“选择丢失”而是状态仍在、只是当前没有能匹配它的普通 Cell。如果希望模式切换后总是回到提示语代码必须在标签回调内同时把 selected 设回 -1如果希望每种模式保存自己的选择则需要不同的数据结构例如为每个模式保留独立编号。以上两种都是将来的产品决策并未出现在工程中。当前实现选择的是共享单值状态所以文章的验证也应该以共享结果为准。理解现状后再考虑扩展比先假设页面存在隐式重置逻辑要安全得多。这种矩阵思维也有助于解释“为什么有时切换标签只改变内容不改变底部文字”。底部提示只读取 selected没有读取 mode标签栏和条件分支只读取 mode没有读取 selected。ArkUI 的状态更新会使依赖状态的表达式重新求值但不会凭空改变另一个没有被赋值的状态。用依赖关系观察页面能避免把每次刷新想成“所有内容被随机重置”。在这个练习页中两条依赖链交叉在普通数字格上数字格既存在于特定 mode 的分支内又读取 selected 来决定背景。为什么焦点内容不能当作跨列示例“大卡加小卡”是常见布局外观因此很多人看到混合模式会立刻想到跨列。页面结构却给出了一个很好的反例焦点内容位于 Grid 之前属于包住整段内容的 Column因为自身的宽度是 100%所以它填满白卡的内部宽度。小 Grid 作为后一个兄弟节点从新的一行开始自己的两列只影响 10 到 13。两者之间不是同一个 Grid 内的占位关系而是普通纵向布局中的上下关系。这种结构有一个直接的观察方法先确定 Grid 的内容范围。混合模式的 Grid 只包含 ForEach 和四个 GridItem焦点 Text 位于范围之外。只要某个元素不在 Grid 的子树中就谈不上由该 Grid 的列轨道来分配它也谈不上占据该 Grid 的多列。页面没有为任何 GridItem 设置跨列参数所以这里不承担演示跨列 API 的任务。从视觉设计上当前结构仍然有清楚的层级标题与说明先交代这一块的主题高度为 140 的橙色块抢占第一视觉焦点下方四个高度为 92 的小格提供重复节奏。白卡的 16 内边距、内部space: 10和小 Grid 的 10 间隔让这几个部分有一致留白。它适合用来练习如何将 Column 与 Grid 组合而不适合据此学习网格中不规则占位。学习时先分清容器边界后面真的接触跨列属性时更容易验证目标元素是否放在正确 Grid 内。焦点内容的点击行为也强调了这种独立性。普通格共享数字格结构因此都有深色覆盖色和数值文本焦点内容是单独的 Text因此只拥有它自己显式写下的点击赋值、固定橙色背景、22 字号和 140 高度。它与普通格共用的只是页面的 selected 状态。共享状态不代表共享样式或共享布局容器正如都写 selected 不代表点击后都将背景改为同一种颜色。若未来要把它真正做成跨列网格组件结构必须改变焦点项需要成为目标 Grid 的 GridItem并且为该项目配置相应的占位规则同时重新考虑小格的流向和行高。那样的方案会产生不同的布局约束不能简单在当前大卡后面补一句“跨两列”就完成。保留这种差异可以避免把一个视觉效果误记为某个尚未调用的 API。从截图回到页面结构的观察方法两张页面截图分别展示默认分支和点选“自适应”后的外观。截图不能替代页面实现但能帮助发现几个很具体的对应关系模式栏的选中蓝与默认偶数卡的蓝都为#2563EB未选中模式块比页面背景稍深来自#F1F5F9内容卡在浅灰蓝页面上显得突出是白色背景和圆角共同造成的而非阴影。观察截图时还应避免得出它没有展示的结论。首图没有发生选择操作因此底部展示的是引导文案不能仅靠它证明选中背景如何变化第二张图显示了四列但不能证明它会按设备宽度自动改列数两张图都没有混合模式因此不能用它们判断焦点内容是否跨列。对这些问题应结合页面状态、条件分支和组件层级检查。截图负责显示一次运行状态页面结构负责说明规则。实际调试中可以临时在脑中把页面切成四块头部信息、模式栏、当前内容、提示区。若头部颜色或编号不对看第一个 Row若标签颜色和分支不一致看 mode 的比较与点击赋值若数字的行列不对看当前 Grid 的列模板、ForEach 数组与间隙若点击后提示不对看 selected 是否被赋值以及底部判断若大卡的位置误以为属于小 Grid看它是否确实位于 Grid 的子树内。这个按层级找问题的过程不依赖玄学调整也不会把所有现象都归咎于 Grid。页面的修饰器写在同一行时视觉上会显得很密集但仍可以按“内容、尺寸、外观、事件、状态条件”分段阅读。例如数字格先决定显示数字再设置字号与文字颜色再设置宽高和 padding再计算背景与圆角最后附上点击回调。标签 Text 也是先写文案和字色、再分配宽度与对齐、再设置 padding 背景圆角、最后写点击。按这个顺序读能较快判断一条修饰器是在影响布局还是在影响状态反馈。面向初学者的复盘清单观察这页后可以用几个问题检查自己是否真正区分了页面事实。第一默认状态为什么是三列答案不应只是“截图这样显示”而应是 mode 初始为 0且该分支中的模板是三个等分轨道。第二为什么点 6 后只有 6 变深因为每个可见数字格都比较同一 selected 与自己的 value只有 6 相等。第三为什么点焦点内容后底部显示 99、橙色卡却不变因为焦点 Text 写入 99却没有背景条件表达式。第四为什么“自适应”模式在截图里有四列因为页面明确给了四个等分轨道不能将它说成根据屏幕算出的列数。第五为什么三种模式的普通格高度相同但宽度不同因为数字格高度固定为 92而宽度填满各自列轨道。第六为什么切换模式后有时仍会看见被选中数字因为 selected 没有重置且新分支恰好有同一个 value。能够逐一回答这些问题就已经抓住了这张练习页比单纯背 API 更有价值的部分。在此基础上可以按从外到内的顺序观察页面先看 Scroll 和最外层 Column确认整页的滚动与留白再看页头 Row 和模式 Row确认 mode 的变化位置再看三个条件分支列出每个 Grid 的数组、颜色和模板最后看 Builder 与底部提示确认 selected 的写入与读取。不要一开始就逐条背fontSize和borderRadius因为这些样式值只有放进状态和容器关系后才有清楚作用。本页也给出了一个克制的扩展方向如果业务真的出现需求再分别加上相应能力。想要响应式列数就设计尺寸条件和模板切换想要不规则网格就把需要占位的项目放入 Grid 并添加对应布局规则想要大量数据就单独评估适合的按需创建方案想让选择状态按模式隔离就调整状态模型。每一项都应配套新的实现与验证场景。它们不该被倒灌回当前简单示例成为“看起来很完整”的虚假描述。回到最初的目标这张页面以极少的状态、静态的短数组和三个模板展示了一个完整但边界明确的练习闭环用户可见模式切换能看到三种列数组织能点选普通格能从底部文字确认状态更新也能通过混合模式理解 Column 和 Grid 可以并用。把这条闭环读透之后再面对更复杂的 ArkTS 页面仍可先问同样的三个问题谁提供布局轨道哪些项目进入轨道哪一份状态决定当前外观这比为一个并未实现的“高级网格应用”添加大量设想更有学习价值。
返回列表