鸿蒙 Next ArkTS 布局精讲Flex 主轴对齐 justifyContent 五种模式完整指南一、前言在鸿蒙 Next 应用开发中布局是一切 UI 的基石。justifyContent属性控制着 Flex 容器内子项在主轴方向上的排列策略是写出看着舒服、逻辑清晰界面的关键。本文将从概念到代码落地结合一个可直接运行的实战案例让你一次看懂全部六种对齐模式。二、Flex 布局基础2.1 什么是 Flex 布局Flex弹性布局是鸿蒙 ArkUI 中最核心的布局容器之一。与Row/Column相比Flex提供了更丰富的子项排列控制主轴方向directionRow水平或 Column垂直主轴对齐justifyContent子项在主轴上的分布方式交叉轴对齐alignItems子项在交叉轴上的对齐方式换行wrap是否允许子项折行2.2 主轴与交叉轴理解justifyContent必须先理解主轴当direction: Row时主轴为水平方向从左到右当direction: Column时主轴为垂直方向从上到下。justifyContent始终作用于主轴方向。三、justifyContent 六种模式详解3.1 FlexAlign.Start默认值所有子项从主轴的起始位置开始紧密排列尾部留出空白。水平 [■ ■ ■ ■ ■]···········适用场景导航栏左侧菜单项、表单标签前的图标列表、左对齐布局需求。3.2 FlexAlign.Center所有子项整体在主轴居中两侧空白均匀。水平 ·····[■ ■ ■ ■ ■]·····适用场景模态框按钮组、页面正中的功能图标、需要视觉对称的场景。3.3 FlexAlign.End所有子项从主轴结束位置开始紧密排列首部留出空白。水平 ·······[■ ■ ■ ■ ■]适用场景页面右下角的浮动操作按钮、聊天框右侧的发送按钮组。3.4 FlexAlign.SpaceBetween首子项贴起点末子项贴终点剩余空间均匀分布在子项之间。水平 [■]·······[■]·······[■]·······[■]·······[■]适用场景底部导航栏 Tab、商品列表三栏分布。“首尾贴边、中间均分”。至少 2 个子项效果才明显单子项时等同于 Start。3.5 FlexAlign.SpaceAround每个子项两侧空间相等。首尾子项外侧空间是中间子项两侧空间的一半。水平 ··[■]··[■]··[■]··[■]··[■]··公式设容器宽 W子项宽和 S子项数 N首尾间隙 G中间间隙 2G则W S 2N*G得G (W-S)/(2N)。适用场景勋章标签展示、功能图标网格。3.6 FlexAlign.SpaceEvenly所有间距含首尾完全相等最数学对称的方式。水平 ····[■]····[■]····[■]····[■]····[■]····公式W S (N1)*G得G (W-S)/(N1)。适用场景底部操作栏等距图标、分页指示器圆点排列。3.7 三者对比速查模式首尾间隙中间间隙公式特点SpaceBetween0均分剩余(W-S)/(N-1)首尾贴边SpaceAroundG2G(W-S)/(2N)两侧等宽SpaceEverlyGG(W-S)/(N1)完全等距四、完整代码实战下面给出完整可运行示例项目结构如下entry/src/main/ets/pages/ ├── Index.ets # 导航首页 └── FlexJustifyContentDemo.ets # 主轴对齐演示页4.1 导航首页Index.etsimport{router}fromkit.ArkUI;EntryComponentstruct Index{build(){Column({space:20}){Text(鸿蒙 ArkTS 布局示例).fontSize(24).fontWeight(FontWeight.Bold).margin({top:40});Text(点击下方卡片体验布局效果).fontSize(14).fontColor(#888888);Column({space:12}){Row({space:8}){Text(≡).fontSize(28).fontWeight(FontWeight.Bold).fontColor(#007AFF);Column({space:4}){Text(Flex 主轴对齐).fontSize(18).fontWeight(FontWeight.Medium);Text(justifyContent 五种模式 · Row / Column 方向切换).fontSize(12).fontColor(#888888);}.alignItems(HorizontalAlign.Start);}.width(100%);Text(Start | Center | End | SpaceBetween | SpaceAround | SpaceEvenly).fontSize(11).fontColor(#007AFF).width(100%);}.width(90%).padding(16).backgroundColor(#FFFFFF).borderRadius(12).shadow({radius:6,color:#30000000,offsetX:0,offsetY:3}).onClick((){router.pushUrl({url:pages/FlexJustifyContentDemo});})Text(点击上方卡片进入演示).fontSize(12).fontColor(#CCCCCC).margin({top:20});}.width(100%).height(100%).backgroundColor(#F5F5F5).alignItems(HorizontalAlign.Center);}}4.2 核心演示页FlexJustifyContentDemo.etsinterfaceJustifyItem{align:FlexAlign;label:string;desc:string;}interfaceDirectionOption{value:FlexDirection;label:string;}EntryComponentstruct FlexJustifyContentDemo{StateprivatecurrentDirection:FlexDirectionFlexDirection.Row;privatereadonlydirectionOptions:DirectionOption[][{value:FlexDirection.Row,label:水平主轴 (Row)},{value:FlexDirection.Column,label:垂直主轴 (Column)},];privatereadonlyjustifyList:JustifyItem[][{align:FlexAlign.Start,label:FlexAlign.Start,desc:子项从主轴起点开始紧密排列},{align:FlexAlign.Center,label:FlexAlign.Center,desc:子项在主轴居中对齐},{align:FlexAlign.End,label:FlexAlign.End,desc:子项从主轴终点开始紧密排列},{align:FlexAlign.SpaceBetween,label:FlexAlign.SpaceBetween,desc:首尾子项贴边剩余空间均匀分布在子项之间},{align:FlexAlign.SpaceAround,label:FlexAlign.SpaceAround,desc:每个子项两侧空间相等首尾空间为中间的一半},{align:FlexAlign.SpaceEvenly,label:FlexAlign.SpaceEvenly,desc:所有间距含首尾完全相等},];privatereadonlycolorList:ResourceColor[][#FF6B81,#5B8FF9,#5AD8A6,#F6BD16,#E8684A,];build(){Scroll(){Column({space:16}){Text(Flex 主轴对齐 · justifyContent).fontSize(22).fontWeight(FontWeight.Bold).width(100%).textAlign(TextAlign.Center).padding({top:20,bottom:8});Text(FlexAlign.Start / Center / End / SpaceBetween / SpaceAround / SpaceEvenly).fontSize(13).fontColor(#666666).width(100%).textAlign(TextAlign.Center).padding({bottom:8});Text(切换主轴方向).fontSize(14).fontWeight(FontWeight.Medium).width(100%).padding({left:16});Row({space:12}){ForEach(this.directionOptions,(item:DirectionOption){Button(item.label).fontSize(14).height(36).borderRadius(18).backgroundColor(this.currentDirectionitem.value?#007AFF:#E8E8E8).fontColor(this.currentDirectionitem.value?#FFFFFF:#333333).onClick((){this.currentDirectionitem.value;});});}.width(100%).padding({left:16,right:16,bottom:4});ForEach(this.justifyList,(item:JustifyItem){this.justifyCard(item);});}.width(100%).padding({bottom:32})}.width(100%).height(100%).backgroundColor(#F5F5F5)}BuilderjustifyCard(item:JustifyItem){Column({space:6}){Text(item.label).fontSize(15).fontWeight(FontWeight.Medium).fontColor(#222222).width(100%);Text(item.desc).fontSize(12).fontColor(#888888).width(100%);// ★ 核心Flex 容器 justifyContentFlex({direction:this.currentDirection,justifyContent:item.align}){ForEach(this.colorList,(color:ResourceColor){Stack(){/* 编号由子级自行填充 */}.width(this.currentDirectionFlexDirection.Row?48:100%).height(this.currentDirectionFlexDirection.Row?48:36).backgroundColor(color).borderRadius(6).margin({left:1,right:1,top:1,bottom:1});});}.width(100%).height(this.currentDirectionFlexDirection.Row?60:220).padding(4).backgroundColor(#FFFFFF).borderRadius(8).border({width:1,color:#E0E0E0}).shadow({radius:4,color:#20000000,offsetX:0,offsetY:2})}.width(100%).padding({left:16,right:16})}}4.3 路由注册修改entry/src/main/resources/base/profile/main_pages.json{src:[pages/Index,pages/FlexJustifyContentDemo]}五、ArkTS 语法避坑指南5.1 Object literals as types错误Object literals cannot be used as type declarations原因ArkTS 禁止内联对象字面量作为类型声明。解决定义显式interface。// ❌ 错误privatereadonlyoptions:{value:FlexDirection;label:string}[][...]// ✅ 正确interfaceDirectionOption{value:FlexDirection;label:string;}privatereadonlyoptions:DirectionOption[][...]5.2 FlexDirection/FlexAlign 导入问题错误Module kit.ArkUI has no exported member FlexDirection原因这两个枚举是 ArkUI全局类型无需 import。解决删除import { FlexDirection, FlexAlign } from kit.ArkUI;即可。5.3 overlay 传参错误Argument of type TextAttribute is not assignable to parameter原因.overlay()不接受直接传Text(...)它需要string | CustomBuilder。解决用Stack包裹内容替代 overlay。// ❌ 错误Column().overlay(Text(1).fontSize(16));// ✅ 正确Stack(){Text(1).fontSize(16);}.width(48).height(48).backgroundColor(color);5.4 其他常见错误错误信息原因解决Array literals not inferrable数组元素类型无法推断给变量添加显式类型标注No exported member导入了框架已移除的 API使用 Kit 化新路径kit.ArkUI六、API 24 新特性与变化6.1 Kit 化导入路径API 24 将 API 按功能域归入 Kit 包旧方式API 9~11新方式API 24import router from ohos.routerimport { router } from kit.ArkUIimport window from ohos.windowimport { window } from kit.ArkUIimport hilog from ohos.hilogimport { hilog } from kit.PerformanceAnalysisKit6.2 Builder 传参改进API 24 中Builder支持更灵活的传参方式包括对象参数、可选参数和默认值。本示例中justifyCard(item: JustifyItem)即是典型用法。6.3 Scroll Column vs List当内容量不大、无需复用机制时Scroll()Column()比List()更轻量、更直观。本示例采用了这种组合。七、最佳实践7.1 对齐模式选型建议场景推荐模式原因表单操作按钮确定/取消Center视觉对称顶部导航菜单项Start左上角阅读起点底部工具栏图标SpaceEvenly各图标权重相同卡片标签列表SpaceAround视觉呼吸感更好底部 Tab 导航2-4 项SpaceBetween充分利用屏幕宽度聊天消息时间戳End右侧对齐7.2 结合 alignContent 实现二维对齐当 Flex 容器换行时alignContent控制多行在交叉轴上的分布与justifyContent配合可实现完整二维弹性布局Flex({direction:FlexDirection.Row,wrap:FlexWrap.Wrap,justifyContent:FlexAlign.SpaceEvenly,alignContent:FlexAlign.SpaceBetween,}){/* 子项先水平等距分布多行之间均匀填充 */}7.3 常见布局问题排查问题可能原因解决子项未按预期对齐direction 设置错误确认主轴方向SpaceBetween 无效果只有 1 个子项至少 2 个子项子项溢出容器子项总宽 容器宽添加 wrap 或减小子项尺寸切换方向后布局乱固定宽高未适配用三元表达式动态适配八、扩展练习挑战一嵌套 Flex— 外层 SpaceBetween 分配三个大区每个大区内使用不同 justifyContent 模式。挑战二动画切换— 为方向按钮添加.animation({ duration: 300, curve: Curve.EaseInOut })。挑战三响应式自适应— 让容器宽度随窗口变化验证各模式的稳定性。九、总结本文从 Flex 布局基础出发深入讲解了 justifyContent 六种对齐模式及其数学原理给出了完整可运行示例并覆盖了 ArkTS 语法避坑、API 24 新特性和最佳实践。核心要点justifyContent作用于主轴方向主轴由FlexDirection决定六种模式分三类边界对齐Start/Center/End、空间填充SpaceBetween、均匀分布SpaceAround/SpaceEvenlySpaceAround 与 SpaceEvenly 的区别前者首尾间隙是中间的一半后者所有间距相等ArkTS 严格模式下需用显式interface替代内联对象字面量FlexDirection/FlexAlign 为全局类型无需 importAPI 24推荐 Kit 化导入路径kit.ArkUIBuilder 装饰器更灵活本文配套代码在项目entry/src/main/ets/pages/目录下可直接在 DevEco Studio 中打开运行。
【共创季稿事节】鸿蒙 Next ArkTS 布局精讲:Flex 主轴对齐 justifyContent 五种模式完整指南
发布时间:2026/6/18 22:05:34
鸿蒙 Next ArkTS 布局精讲Flex 主轴对齐 justifyContent 五种模式完整指南一、前言在鸿蒙 Next 应用开发中布局是一切 UI 的基石。justifyContent属性控制着 Flex 容器内子项在主轴方向上的排列策略是写出看着舒服、逻辑清晰界面的关键。本文将从概念到代码落地结合一个可直接运行的实战案例让你一次看懂全部六种对齐模式。二、Flex 布局基础2.1 什么是 Flex 布局Flex弹性布局是鸿蒙 ArkUI 中最核心的布局容器之一。与Row/Column相比Flex提供了更丰富的子项排列控制主轴方向directionRow水平或 Column垂直主轴对齐justifyContent子项在主轴上的分布方式交叉轴对齐alignItems子项在交叉轴上的对齐方式换行wrap是否允许子项折行2.2 主轴与交叉轴理解justifyContent必须先理解主轴当direction: Row时主轴为水平方向从左到右当direction: Column时主轴为垂直方向从上到下。justifyContent始终作用于主轴方向。三、justifyContent 六种模式详解3.1 FlexAlign.Start默认值所有子项从主轴的起始位置开始紧密排列尾部留出空白。水平 [■ ■ ■ ■ ■]···········适用场景导航栏左侧菜单项、表单标签前的图标列表、左对齐布局需求。3.2 FlexAlign.Center所有子项整体在主轴居中两侧空白均匀。水平 ·····[■ ■ ■ ■ ■]·····适用场景模态框按钮组、页面正中的功能图标、需要视觉对称的场景。3.3 FlexAlign.End所有子项从主轴结束位置开始紧密排列首部留出空白。水平 ·······[■ ■ ■ ■ ■]适用场景页面右下角的浮动操作按钮、聊天框右侧的发送按钮组。3.4 FlexAlign.SpaceBetween首子项贴起点末子项贴终点剩余空间均匀分布在子项之间。水平 [■]·······[■]·······[■]·······[■]·······[■]适用场景底部导航栏 Tab、商品列表三栏分布。“首尾贴边、中间均分”。至少 2 个子项效果才明显单子项时等同于 Start。3.5 FlexAlign.SpaceAround每个子项两侧空间相等。首尾子项外侧空间是中间子项两侧空间的一半。水平 ··[■]··[■]··[■]··[■]··[■]··公式设容器宽 W子项宽和 S子项数 N首尾间隙 G中间间隙 2G则W S 2N*G得G (W-S)/(2N)。适用场景勋章标签展示、功能图标网格。3.6 FlexAlign.SpaceEvenly所有间距含首尾完全相等最数学对称的方式。水平 ····[■]····[■]····[■]····[■]····[■]····公式W S (N1)*G得G (W-S)/(N1)。适用场景底部操作栏等距图标、分页指示器圆点排列。3.7 三者对比速查模式首尾间隙中间间隙公式特点SpaceBetween0均分剩余(W-S)/(N-1)首尾贴边SpaceAroundG2G(W-S)/(2N)两侧等宽SpaceEverlyGG(W-S)/(N1)完全等距四、完整代码实战下面给出完整可运行示例项目结构如下entry/src/main/ets/pages/ ├── Index.ets # 导航首页 └── FlexJustifyContentDemo.ets # 主轴对齐演示页4.1 导航首页Index.etsimport{router}fromkit.ArkUI;EntryComponentstruct Index{build(){Column({space:20}){Text(鸿蒙 ArkTS 布局示例).fontSize(24).fontWeight(FontWeight.Bold).margin({top:40});Text(点击下方卡片体验布局效果).fontSize(14).fontColor(#888888);Column({space:12}){Row({space:8}){Text(≡).fontSize(28).fontWeight(FontWeight.Bold).fontColor(#007AFF);Column({space:4}){Text(Flex 主轴对齐).fontSize(18).fontWeight(FontWeight.Medium);Text(justifyContent 五种模式 · Row / Column 方向切换).fontSize(12).fontColor(#888888);}.alignItems(HorizontalAlign.Start);}.width(100%);Text(Start | Center | End | SpaceBetween | SpaceAround | SpaceEvenly).fontSize(11).fontColor(#007AFF).width(100%);}.width(90%).padding(16).backgroundColor(#FFFFFF).borderRadius(12).shadow({radius:6,color:#30000000,offsetX:0,offsetY:3}).onClick((){router.pushUrl({url:pages/FlexJustifyContentDemo});})Text(点击上方卡片进入演示).fontSize(12).fontColor(#CCCCCC).margin({top:20});}.width(100%).height(100%).backgroundColor(#F5F5F5).alignItems(HorizontalAlign.Center);}}4.2 核心演示页FlexJustifyContentDemo.etsinterfaceJustifyItem{align:FlexAlign;label:string;desc:string;}interfaceDirectionOption{value:FlexDirection;label:string;}EntryComponentstruct FlexJustifyContentDemo{StateprivatecurrentDirection:FlexDirectionFlexDirection.Row;privatereadonlydirectionOptions:DirectionOption[][{value:FlexDirection.Row,label:水平主轴 (Row)},{value:FlexDirection.Column,label:垂直主轴 (Column)},];privatereadonlyjustifyList:JustifyItem[][{align:FlexAlign.Start,label:FlexAlign.Start,desc:子项从主轴起点开始紧密排列},{align:FlexAlign.Center,label:FlexAlign.Center,desc:子项在主轴居中对齐},{align:FlexAlign.End,label:FlexAlign.End,desc:子项从主轴终点开始紧密排列},{align:FlexAlign.SpaceBetween,label:FlexAlign.SpaceBetween,desc:首尾子项贴边剩余空间均匀分布在子项之间},{align:FlexAlign.SpaceAround,label:FlexAlign.SpaceAround,desc:每个子项两侧空间相等首尾空间为中间的一半},{align:FlexAlign.SpaceEvenly,label:FlexAlign.SpaceEvenly,desc:所有间距含首尾完全相等},];privatereadonlycolorList:ResourceColor[][#FF6B81,#5B8FF9,#5AD8A6,#F6BD16,#E8684A,];build(){Scroll(){Column({space:16}){Text(Flex 主轴对齐 · justifyContent).fontSize(22).fontWeight(FontWeight.Bold).width(100%).textAlign(TextAlign.Center).padding({top:20,bottom:8});Text(FlexAlign.Start / Center / End / SpaceBetween / SpaceAround / SpaceEvenly).fontSize(13).fontColor(#666666).width(100%).textAlign(TextAlign.Center).padding({bottom:8});Text(切换主轴方向).fontSize(14).fontWeight(FontWeight.Medium).width(100%).padding({left:16});Row({space:12}){ForEach(this.directionOptions,(item:DirectionOption){Button(item.label).fontSize(14).height(36).borderRadius(18).backgroundColor(this.currentDirectionitem.value?#007AFF:#E8E8E8).fontColor(this.currentDirectionitem.value?#FFFFFF:#333333).onClick((){this.currentDirectionitem.value;});});}.width(100%).padding({left:16,right:16,bottom:4});ForEach(this.justifyList,(item:JustifyItem){this.justifyCard(item);});}.width(100%).padding({bottom:32})}.width(100%).height(100%).backgroundColor(#F5F5F5)}BuilderjustifyCard(item:JustifyItem){Column({space:6}){Text(item.label).fontSize(15).fontWeight(FontWeight.Medium).fontColor(#222222).width(100%);Text(item.desc).fontSize(12).fontColor(#888888).width(100%);// ★ 核心Flex 容器 justifyContentFlex({direction:this.currentDirection,justifyContent:item.align}){ForEach(this.colorList,(color:ResourceColor){Stack(){/* 编号由子级自行填充 */}.width(this.currentDirectionFlexDirection.Row?48:100%).height(this.currentDirectionFlexDirection.Row?48:36).backgroundColor(color).borderRadius(6).margin({left:1,right:1,top:1,bottom:1});});}.width(100%).height(this.currentDirectionFlexDirection.Row?60:220).padding(4).backgroundColor(#FFFFFF).borderRadius(8).border({width:1,color:#E0E0E0}).shadow({radius:4,color:#20000000,offsetX:0,offsetY:2})}.width(100%).padding({left:16,right:16})}}4.3 路由注册修改entry/src/main/resources/base/profile/main_pages.json{src:[pages/Index,pages/FlexJustifyContentDemo]}五、ArkTS 语法避坑指南5.1 Object literals as types错误Object literals cannot be used as type declarations原因ArkTS 禁止内联对象字面量作为类型声明。解决定义显式interface。// ❌ 错误privatereadonlyoptions:{value:FlexDirection;label:string}[][...]// ✅ 正确interfaceDirectionOption{value:FlexDirection;label:string;}privatereadonlyoptions:DirectionOption[][...]5.2 FlexDirection/FlexAlign 导入问题错误Module kit.ArkUI has no exported member FlexDirection原因这两个枚举是 ArkUI全局类型无需 import。解决删除import { FlexDirection, FlexAlign } from kit.ArkUI;即可。5.3 overlay 传参错误Argument of type TextAttribute is not assignable to parameter原因.overlay()不接受直接传Text(...)它需要string | CustomBuilder。解决用Stack包裹内容替代 overlay。// ❌ 错误Column().overlay(Text(1).fontSize(16));// ✅ 正确Stack(){Text(1).fontSize(16);}.width(48).height(48).backgroundColor(color);5.4 其他常见错误错误信息原因解决Array literals not inferrable数组元素类型无法推断给变量添加显式类型标注No exported member导入了框架已移除的 API使用 Kit 化新路径kit.ArkUI六、API 24 新特性与变化6.1 Kit 化导入路径API 24 将 API 按功能域归入 Kit 包旧方式API 9~11新方式API 24import router from ohos.routerimport { router } from kit.ArkUIimport window from ohos.windowimport { window } from kit.ArkUIimport hilog from ohos.hilogimport { hilog } from kit.PerformanceAnalysisKit6.2 Builder 传参改进API 24 中Builder支持更灵活的传参方式包括对象参数、可选参数和默认值。本示例中justifyCard(item: JustifyItem)即是典型用法。6.3 Scroll Column vs List当内容量不大、无需复用机制时Scroll()Column()比List()更轻量、更直观。本示例采用了这种组合。七、最佳实践7.1 对齐模式选型建议场景推荐模式原因表单操作按钮确定/取消Center视觉对称顶部导航菜单项Start左上角阅读起点底部工具栏图标SpaceEvenly各图标权重相同卡片标签列表SpaceAround视觉呼吸感更好底部 Tab 导航2-4 项SpaceBetween充分利用屏幕宽度聊天消息时间戳End右侧对齐7.2 结合 alignContent 实现二维对齐当 Flex 容器换行时alignContent控制多行在交叉轴上的分布与justifyContent配合可实现完整二维弹性布局Flex({direction:FlexDirection.Row,wrap:FlexWrap.Wrap,justifyContent:FlexAlign.SpaceEvenly,alignContent:FlexAlign.SpaceBetween,}){/* 子项先水平等距分布多行之间均匀填充 */}7.3 常见布局问题排查问题可能原因解决子项未按预期对齐direction 设置错误确认主轴方向SpaceBetween 无效果只有 1 个子项至少 2 个子项子项溢出容器子项总宽 容器宽添加 wrap 或减小子项尺寸切换方向后布局乱固定宽高未适配用三元表达式动态适配八、扩展练习挑战一嵌套 Flex— 外层 SpaceBetween 分配三个大区每个大区内使用不同 justifyContent 模式。挑战二动画切换— 为方向按钮添加.animation({ duration: 300, curve: Curve.EaseInOut })。挑战三响应式自适应— 让容器宽度随窗口变化验证各模式的稳定性。九、总结本文从 Flex 布局基础出发深入讲解了 justifyContent 六种对齐模式及其数学原理给出了完整可运行示例并覆盖了 ArkTS 语法避坑、API 24 新特性和最佳实践。核心要点justifyContent作用于主轴方向主轴由FlexDirection决定六种模式分三类边界对齐Start/Center/End、空间填充SpaceBetween、均匀分布SpaceAround/SpaceEvenlySpaceAround 与 SpaceEvenly 的区别前者首尾间隙是中间的一半后者所有间距相等ArkTS 严格模式下需用显式interface替代内联对象字面量FlexDirection/FlexAlign 为全局类型无需 importAPI 24推荐 Kit 化导入路径kit.ArkUIBuilder 装饰器更灵活本文配套代码在项目entry/src/main/ets/pages/目录下可直接在 DevEco Studio 中打开运行。