行业资讯
📅 2026/7/9 6:50:19
鸿蒙新特性:Grid 网格布局——构建应用抽屉
手机桌面是一个典型的网格布局——4 列或 5 列的图标矩阵每行等宽排列点击即可打开应用。这种等宽多列、自动换行的布局需求在移动端无处不在应用抽屉、照片网格、商品列表、分类导航……都是网格布局的典型场景。HarmonyOS NEXT ArkUI 提供了 Grid 组件——一个高性能的网格布局容器配合 GridItem 组件灵活控制每列的内容和样式。本文将深入讲解 Grid/GridItem 的 API 和使用技巧并构建一个应用抽屉——支持动态列数切换、分类筛选和名称搜索。关键词HarmonyOS、ArkUI、Grid、GridItem、网格布局、应用抽屉、列数切换、分类筛选一、Grid 组件 API1.1 基本用法Grid(){ForEach(this.apps,(app:AppInfo){GridItem(){Column(){Text(app.icon).fontSize(32)Text(app.name).fontSize(12)}}},(app:AppInfo)app.name)}.columnsTemplate(1fr 1fr 1fr 1fr).rowsGap(10).columnsGap(10)核心参数与属性参数/属性类型说明.columnsTemplate()string列模板如1fr 1fr 1fr 1fr表示 4 等宽列.rowsTemplate()string行模板可选通常由内容撑开即可.rowsGap()Length行间距.columnsGap()Length列间距.width()/.height()Length容器尺寸1.2 columnsTemplate 详解columnsTemplate是 Grid 最核心的属性——它决定了网格有多少列以及每列的宽度。它使用 CSS Grid 的fr单位语法值含义1fr 1fr 1fr3 列等宽1fr 1fr 1fr 1fr4 列等宽1fr 1fr 1fr 1fr 1fr5 列等宽1fr 2fr 1fr3 列中间列宽度是两边的 2 倍100px 1fr 1fr3 列第一列固定 100px后两列等分剩余空间frfraction是弹性单位——所有fr值相加后按比例分配可用空间。Demo 中使用纯1fr模板实现等宽列getColumnsTemplate():string{if(this.columnCount3)return1fr 1fr 1fr;if(this.columnCount5)return1fr 1fr 1fr 1fr 1fr;return1fr 1fr 1fr 1fr;}1.3 动态列数切换Demo 通过在页面右上角提供 3/4/5 三个列数按钮让用户实时切换网格密度StatecolumnCount:number4;// 切换按钮Text(3).onClick((){this.columnCount3;})Text(4).onClick((){this.columnCount4;})Text(5).onClick((){this.columnCount5;})选中按钮为蓝底白字#1677FF背景 #FFFFFF文字未选中为灰底灰字#F2F3F5背景 #888899文字。Grid 的.columnsTemplate(this.getColumnsTemplate())会随着columnCount变化自动重新计算列模板Grid 中的内容即时重新排列——不需要手动刷新任何内容。1.4 GridItem 样式每个GridItem包含应用的图标和名称GridItem(){Column(){Text(app.icon)// emoji 图标32sp.fontSize(32).margin({bottom:6})Text(app.name)// 应用名称12sp.fontSize(12).fontColor(#1a1a2e).maxLines(1).textOverflow({overflow:TextOverflow.Ellipsis})}.width(100%).padding({top:16,bottom:12}).borderRadius(12).backgroundColor(app.bgColor.concat(18))// 半透明背景}图标使用 emoji 字符如 32sp 字号在网格单元中足够醒目。名称限制单行 省略号防止长名称撑破布局。背景色使用应用的品牌色 18后缀即 9% 透明度形成半透明的淡色背景——比纯色背景更柔和用户能感知到不同应用的色调但不会过于刺眼。二、应用抽屉的整体设计2.1 页面架构AppDrawerPage ├── 标题栏 — 应用抽屉 当前应用数 ├── 搜索栏圆角 pill 风格 ├── 操作栏 │ ├── 分类筛选标签横向滚动 │ └── 列数切换按钮3/4/5 ├── Grid 网格区域 │ └── GridItem应用图标 名称 ├── 空状态提示 └── 底部信息栏列数 总应用数2.2 数据类设计classAppInfo{name:string;// 应用名称icon:string;// emoji 图标category:string;// 分类标签bgColor:string;// 品牌色用于半透明背景constructor(name:string,icon:string,category:string,bgColor:string){this.namename;this.iconicon;this.categorycategory;this.bgColorbgColor;}}AppInfo的bgColor字段被巧用——不仅是数据属性也直接用于 UI 渲染.backgroundColor(app.bgColor.concat(18))。这种数据驱动视觉的模式避免了在 UI 层做颜色映射逻辑数据本身就包含了视觉信息。2.3 应用数据Demo 包含 19 款应用覆盖 5 个分类分类应用数量社交微信、QQ、微博、钉钉4工具计算器、时钟⏰、日历、文件管理、翻译5娱乐音乐、视频、游戏中心、直播4购物商城、优惠券、二手交易♻️3阅读新闻、电子书、知识社区3每个应用的 emoji 图标尽量贴近实际用途——微信的 、音乐的 、商城的 ——让用户在 Demo 中也能感受到真实的应用抽屉氛围。三、搜索与筛选3.1 搜索过滤if(this.searchText.length0){letkeywordthis.searchText;letfiltered:AppInfo[][];for(leti0;iapps.length;i){if(apps[i].name.indexOf(keyword)0){filteredfiltered.slice().concat(apps[i]);}}appsfiltered;}使用String.indexOf()做简单的子串匹配——输入音可以搜到音乐输入乐也能搜到。不需要完整的拼音搜索或模糊匹配但对于 19 款应用的 Demo 规模来说已经足够实用。3.2 分类筛选6 个标签全部 5 个分类使用横向 Scroll 容器确保在小屏手机上也能完整显示Scroll(){Row(){ForEach(this.getCategories(),(cat:string){Text(this.getCategoryLabel(cat)).fontSize(12).fontColor(catthis.activeCategory?#FFFFFF:#666677)// ....onClick((){this.activeCategorycat;})})}}.scrollBar(BarState.Off).layoutWeight(1)选中标签蓝底白字未选中灰底灰字。横向滚动 隐藏滚动条保持视觉整洁。3.3 搜索分类双重过滤搜索和分类是叠加关系——先按分类过滤再按搜索词过滤getFilteredApps():AppInfo[]{letappsthis.getAllApps();// 第一层分类过滤if(this.activeCategory!all){/* 按分类过滤 */}// 第二层搜索过滤if(this.searchText.length0){/* 按关键词过滤 */}returnapps;}用户可以组合使用先选择工具分类看所有工具类应用再搜计只看计算器——两个维度的过滤协同工作。3.4 空状态当筛选结果为空时显示差异化提示if(this.getFilteredApps().length0){Column(){Text(没有找到应用).fontSize(14).fontColor(#BBBBCC)Text(试试切换分类或修改搜索关键词).fontSize(12).fontColor(#CCCCDD).margin({top:4})}.width(100%).padding({top:48,bottom:48})}提示引导用户切换分类或修改搜索关键词——两个可操作的下一步动作而非简单的无结果。四、列数切换与视觉密度4.1 三种密度列数columnsTemplate适用场景31fr 1fr 1fr大图标、老年模式、信息密集型卡片41fr 1fr 1fr 1fr标准手机桌面默认51fr 1fr 1fr 1fr 1fr小图标、高密度、大屏手机每种密度下GridItem 的图标大小32sp保持不变但单元宽度不同——3 列时单元最宽5 列时最窄。用户可以根据屏幕大小和个人偏好选择合适的密度。4.2 切换按钮设计列数切换使用三轮圆形按钮位于分类标签右侧[3] [4] [5]选中为蓝底白字#1677FF未选中为灰底灰字#F2F3F5。按钮尺寸 26×26dp足够小不会占据太多空间又足够大可以用手指点击。4.3 底部信息网格下方显示当前列数和总应用数当前 4 列网格 · 共 19 款应用帮助用户感知当前视图参数也让页面底部不显得空洞。五、Grid vs WaterFlow vs List三个组件的对比维度GridWaterFlowList布局方式等宽多列行对齐不等高瀑布流单列垂直列表列控制columnsTemplate精确控制columnsTemplate 自动排列无需列控制子项高度通常一致各不相同通常一致典型场景应用抽屉、照片网格商品发现、Pinterest联系人、消息列表滚动方向垂直默认垂直默认垂直/水平性能高虚拟化高虚拟化高虚拟化选择建议每个子项尺寸相似、需要规整的行列对齐 →Grid每个子项高度不同、需要充分利用空间 →WaterFlow简单的线性排列、需要分组粘性头 →List六、交互流程演示6.1 默认视图进入页面19 款应用以 4 列网格排列。每行最多 4 个应用图标——微信、QQ、微博、钉钉在第一行。所有应用半透明彩色背景视觉丰富而不杂乱。标题栏显示19 个。6.2 搜索应用在搜索栏输入音。Grid 立即刷新只显示音乐一个匹配项。标题栏变为1 个。清空搜索栏Grid 恢复显示全部 19 款应用。输入不存在。Grid 显示空状态“没有找到应用” “试试切换分类或修改搜索关键词”。6.3 分类筛选点击工具分类标签。Grid 只显示 5 款工具类应用计算器、时钟、日历、文件管理、翻译。标题栏变为5 个。再在搜索栏输入计。双重过滤生效只显示计算器。点击全部恢复所有应用。6.4 列数切换点击列数按钮3——网格变为 3 列每行最多 3 个应用。图标间距变宽视觉更松散。点击5——网格变为 5 列每行最多 5 个应用。图标间距变窄信息密度更高。点击4恢复默认。底部信息栏同步更新“当前 3 列网格” → “当前 5 列网格” → “当前 4 列网格”。6.5 点击应用点击任意应用图标。Toast 提示打开 XXX。背景色提供触摸反馈的视觉感知。七、总结本文通过应用抽屉这个实战案例全面讲解了 ArkUI Grid 网格布局组件的使用方法。核心知识点包括Grid 基础 APIcolumnsTemplate()列模板 rowsGap()/columnsGap()间距控制columnsTemplate 语法1fr 1fr 1fr 1fr表示 4 等宽列fr是弹性比例单位动态列数切换State columnCount→getColumnsTemplate()动态生成模板字符串GridItem 样式居中对齐的 icon name 半透明品牌色背景双重过滤分类筛选 关键词搜索的叠加过滤逻辑空状态设计筛选无结果时的引导性提示Grid vs WaterFlow vs List三种布局组件的对比与场景选择网格布局是移动端信息展示的核心模式之一。从手机桌面到相册网格从电商首页到设置入口——Grid 组件提供的columnsTemplate机制让开发者可以精确控制每行的列数和每列的宽度。配合搜索和筛选一个灵活的应用抽屉或任意图标网格就能轻松构建。