当前位置: 首页 > news >正文

HarmonyOS开发实战:笔友-条件渲染与可见性控制:if/Visibility 对比

前言

在 ArkUI 声明式开发范式中,条件渲染可见性控制是两种不同的 UI 控制策略。if/else通过条件判断决定是否创建组件,而Visibility通过控制组件的可见性属性决定是否显示。它们各有适用场景,错误的选择可能导致性能问题或状态丢失。

本文将以开源鸿蒙笔友通信应用 xiexin 的SplashPage.etsIndex.etsComposePage.ets为蓝本,详细剖析if/elseVisibility的语义、差异、性能对比,以及它们在不同场景下的最佳实践。

提示:本文假设你已经了解 ArkUI 声明式开发的基本概念。如果还不熟悉,建议先阅读前十七篇文章。

一、条件渲染的两种方式

1.1 if/else 条件渲染

if/else通过条件判断决定是否创建组件

// SplashPage.ets — if/else 切换按钮if(this.currentPage===2){Button('开始写信').fontSize(16).fontColor(AppColors.WHITE).backgroundColor(AppColors.PRIMARY).borderRadius(24).width(200).height(48).onClick(()=>{router.replaceUrl({url:'pages/Index'});})}else{Button('下一步').fontSize(16).fontColor(AppColors.PRIMARY).backgroundColor(AppColors.AMBER_LIGHT).borderRadius(24).width(200).height(48).onClick(()=>{this.currentPage=this.currentPage+1;})}

1.2 Visibility 可见性控制

Visibility通过属性控制组件是否可见

// Visibility 的三种状态Visibility.None// 完全不可见,不占布局空间Visibility.Hidden// 不可见,但保留布局占位Visibility.Visible// 可见// 使用示例Text('隐藏文字').visibility(Visibility.Hidden)

二、if/else 与 Visibility 的核心差异

2.1 对比表格

维度if/elseVisibility
组件创建条件为 true 时创建始终创建
内存占用条件为 false 时不占用始终占用内存
布局空间条件为 false 时不占布局None不占,Hidden占位
状态保留条件变化时销毁重建,状态丢失状态始终保留
适用场景不常切换、内容较多频繁切换、内容较少
性能开销创建/销毁有开销始终存在,无切换开销

2.2 选择决策树

组件是否需要频繁切换显示/隐藏? ├── 是 → Visibility │ 组件是否需要保留状态? │ ├── 是 → Visibility.Hidden(保留占位) │ └── 否 → Visibility.None(不占布局) └── 否 → if/else 组件内容是否较多? ├── 是 → if/else(减少内存占用) └── 否 → if/else(默认选择)

三、xiexin 中的条件渲染

3.1 SplashPage 的按钮切换

// SplashPage.ets — 使用 if/else 切换按钮if(this.currentPage===2){Button('开始写信').fontSize(16).fontColor(AppColors.WHITE).backgroundColor(AppColors.PRIMARY).borderRadius(24).width(200).height(48).fontWeight(FontWeight.Medium).onClick(()=>{router.replaceUrl({url:'pages/Index'});})}else{Button('下一步').fontSize(16).fontColor(AppColors.PRIMARY).backgroundColor(AppColors.AMBER_LIGHT).borderRadius(24).width(200).height(48).fontWeight(FontWeight.Medium).onClick(()=>{this.currentPage=this.currentPage+1;})}

这里使用if/else是正确的选择,因为:

  1. 切换频率低:用户只会在引导页翻页时切换一次
  2. 组件内容少:按钮只有 10 行代码,创建/销毁开销小
  3. 状态不保留:切换按钮时不需要保留上一个按钮的状态

3.2 Index 页面的空状态判断

// Index.ets — 使用 if/else 判断空状态if(this.letters.length===0){EmptyState({title:'还没有信件,去写第一封吧',subtitle:'每一封信都是一段温暖的旅程'})}else{Scroll(){Column({space:12}){ForEach(this.getSortedLetters(),(letter:Letter)=>{this.LetterCard(letter)},(letter:Letter)=>letter.id.toString())}.padding({left:16,right:16,bottom:20})}.layoutWeight(1).scrollBar(BarState.Off)}

这里使用if/else是正确的选择,因为:

  1. 切换频率低:从"空状态"到"有信件"只切换一次
  2. 内容差异大:空状态和信件列表的 UI 完全不同
  3. 内存优化:空状态时不会创建 100 个 ListItem 组件

3.3 ComposePage 的面板展开

// ComposePage.ets — 使用 @State 布尔值控制面板展开@StateshowHonorificPanel:boolean=false;@StateshowGreetingPanel:boolean=false;@StateshowClosingPanel:boolean=false;@StateshowWordPanel:boolean=false;@StateshowPaperPanel:boolean=false;@StateshowFormatPanel:boolean=false;// 在 build 中使用 if 条件渲染if(this.showHonorificPanel){this.HonorificPanel()}if(this.showGreetingPanel){this.GreetingPanel()}

这里使用if条件渲染,但应该考虑Visibility的优化:

// 优化:使用 Visibility 保留面板展开时的滚动位置HonorificPanel().visibility(this.showHonorificPanel?Visibility.Visible:Visibility.None)

四、if/else 的常见陷阱

4.1 状态丢失

// 问题:if/else 切换时,子组件状态丢失@Entry@Componentstruct MyComponent{@StateshowInput:boolean=false;build(){Column(){if(this.showInput){TextInput({placeholder:'输入内容'})}Button('切换').onClick(()=>{this.showInput=!this.showInput;})}}}

showInputtrue变为false再变为true时,TextInput组件被销毁重建,用户输入的内容丢失。

4.2 动画中断

// 问题:if/else 切换时,动画被中断if(this.isVisible){Text('Hello').opacity(1).animation({duration:300})}else{// 组件不存在,动画无法播放}

4.3 性能问题

// 问题:频繁切换时,if/else 导致大量创建/销毁if(this.isVisible){ForEach(this.largeArray,(item)=>{// 大量组件},(item)=>item.id.toString())}

五、Visibility 的常见陷阱

5.1 布局空间问题

// Visibility.Hidden 保留布局空间Column(){Text('标题').visibility(Visibility.Hidden)// 标题不可见,但占位还在Text('内容')}

5.2 与动画的配合

// 使用 opacity 实现平滑过渡@StateisVisible:boolean=false;Text('Hello').opacity(this.isVisible?1:0).animation({duration:300,curve:Curve.EaseOut})

六、if/else 与 Visibility 的配合使用

6.1 组合策略

// 组合使用:if/else 控制创建,Visibility 控制显示@StateisComponentCreated:boolean=false;@StateisComponentVisible:boolean=false;if(this.isComponentCreated){Text('Hello').visibility(this.isComponentVisible?Visibility.Visible:Visibility.Hidden)}

6.2 实际应用

// 场景:弹窗的创建和显示@StateisDialogCreated:boolean=false;@StateisDialogVisible:boolean=false;// 创建弹窗(仅一次)if(this.isDialogCreated){CustomDialog({visible:this.isDialogVisible,onClose:()=>{this.isDialogVisible=false;}})}// 显示/隐藏弹窗(多次切换)Button('显示弹窗').onClick(()=>{this.isDialogCreated=true;this.isDialogVisible=true;})

七、xiexin 中的可见性控制优化

7.1 当前实现

xiexin 当前主要使用if/else进行条件渲染:

// SplashPage: if/else 切换按钮if(this.currentPage===2){/* 开始写信按钮 */}else{/* 下一步按钮 */}// Index: if/else 判断空状态if(this.letters.length===0){/* 空状态 */}else{/* 信件列表 */}// ComposePage: if 控制面板展开if(this.showHonorificPanel){/* 称谓面板 */}

7.2 优化建议

当前位置当前方式建议方式理由
SplashPage 按钮if/else保持 if/else切换频率低,内容简单
Index 空状态if/else保持 if/else内容差异大,内存优化
ComposePage 面板if改为 Visibility面板切换频繁,需保留状态

八、条件渲染的性能对比

8.1 创建/销毁开销

对比项if/elseVisibility
首次创建需要创建需要创建
条件变化销毁重建不需要创建
多次切换每次创建/销毁无额外开销

8.2 内存占用

对比项if/elseVisibility
条件为 false不占用内存占用内存
条件为 true占用内存占用内存
1000 项列表仅创建 1000 项始终创建 1000 项

九、Visibility 与动画的配合

9.1 淡入淡出效果

@Entry@Componentstruct FadeExample{@StateisVisible:boolean=false;build(){Column(){Text('Hello').opacity(this.isVisible?1:0).animation({duration:300,curve:Curve.EaseOut})Button('切换').onClick(()=>{this.isVisible=!this.isVisible;})}}}

9.2 滑动展开效果

@Entry@Componentstruct SlideExample{@StateisExpanded:boolean=false;build(){Column(){Button('展开').onClick(()=>{animateTo({duration:300},()=>{this.isExpanded=!this.isExpanded;})})// 使用 if 控制创建,动画控制显示if(this.isExpanded){Text('内容').opacity(1).animation({duration:300})}}}}

十、从 xiexin 看条件渲染与可见性控制

xiexin 中条件渲染的使用体现了"场景决定选择"的原则:

  1. 引导页按钮切换:使用if/else,因为切换频率低、内容简单
  2. 空状态判断:使用if/else,因为内容差异大、内存占用差别大
  3. 编辑面板展开:使用if(实际上应该用Visibility),因为切换频繁、需要保留状态

每个场景的选择都基于实际的业务需求,而非盲目使用某一种方式。

总结

本文详细剖析了 HarmonyOS ArkUI 的if/else条件渲染和Visibility可见性控制的语义、差异、性能对比,以及它们在不同场景下的最佳实践。

理解条件渲染与可见性控制的关键是把握"两个原则":创建原则(if/else 决定是否创建)和显示原则(Visibility 决定是否显示)。创建原则适用于"不常切换、内容较多"的场景,显示原则适用于"频繁切换、需要保留状态"的场景。

至此,我们已经完成了 HarmonyOS 应用开发实战系列的第二阶段——ArkUI 声明式 UI 进阶。从下一篇文章开始,我们将进入第三阶段——组件化与通用组件,深入剖析 xiexin 中如何通过组件封装实现 UI 复用。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源

  • 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
  • HarmonyOS 渲染控制概述:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-rendering-control-overview
  • HarmonyOS if/else 条件渲染:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-rendering-control-if
  • HarmonyOS ForEach 渲染控制:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-rendering-control-foreach
  • HarmonyOS LazyForEach 渲染控制:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-rendering-control-lazyforeach
  • HarmonyOS 高性能编程实践:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-high-performance-programming
  • HarmonyOS 动画概述:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-animation
  • HarmonyOS 状态管理概述:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-state-management-overview
  • HarmonyOS 自定义组件:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-custom-components
http://www.jsqmd.com/news/1265130/

相关文章:

  • 智慧交通仿真:混合建模与智能体行为优化实践
  • AI工具如何优化软件工程毕业设计:降重、代码与文档实战
  • 深入解析I/O控制寄存器:从原理到实战,优化嵌入式系统性能与功耗
  • Windows下载、安装godot-4.7.1-stable(附安装包Godot_v4.7.1-stable_win64.exe.zip)
  • 5分钟搞定:百度网盘解析工具的终极使用指南
  • AI论文降重工具与技巧全攻略
  • AI绘图显存优化:Z-Image Turbo量化技术解析
  • CUDA Graph技术解析:原理、优化与实践指南
  • 教材编写低查重方法与工具链配置实战指南
  • 鸿蒙 PC Markdown 编辑器 ArkUI 界面分层:从超大工作台到可维护组件边界
  • Windows虚拟门禁系统部署全攻略
  • 3步搞定百度网盘限速:开源解析工具实战指南
  • 泰州出发西藏跟团游怎么选?这份本地地接社的纯玩攻略请收好| 附:旅行社电话 - 西藏康泰旅行社
  • Ubuntu 22.04源码编译安装ROOT v6.32.00指南
  • 基于YOLOv5的道路坑洼检测技术实践
  • C/C++指针深度解析:从内存模型到智能指针实战
  • 智能薪酬计算系统:AI与微服务在财务数字化转型中的应用
  • 开源AI解决方案:IOC架构与图像搜索实践
  • Windows C++开发环境配置指南:Visual Studio与VSCode+MinGW双路径详解
  • AI图像生成技术常见问题与解决方案
  • 企业级办公AI Agent系统开发实战与架构解析
  • GPT-5.4 生成的单元测试你敢直接 commit?覆盖率85%背后的四重陷阱与Mock实战
  • 深度学习注意力机制原理与工程实践详解
  • 大模型如何从博学到善言:三步提升对话效果
  • (2026最新)新余漏水检测维修一站式上门服务-本地专业防水补漏公司TOP5推荐:暗管漏水检测精准定位 - 安佳防水
  • 【本地大模型搭建终极指南】:20年AI架构师亲授7步零基础部署私有LLM,错过再等一年!
  • 吴恩达Agentic AI实战:智能体开发核心技术解析
  • 深入解析TI CC13xx/CC26xx AUX传感器控制器GPIO与事件寄存器配置
  • 技术人员税务规划指南:从马斯克案例到实战策略
  • Windows终端美化:WSL+Zsh打造macOS级体验