文章目录
-
- 一、属性签名与参数说明
- 二、三个枚举值的核心区别
- 三、示例一:三种枚举值的直观对比
-
- [3.1 代码](#3.1 代码)
- [3.2 布局效果分析](#3.2 布局效果分析)
- [四、示例二:动态切换 visibility](#四、示例二:动态切换 visibility)
-
- [4.1 代码](#4.1 代码)
- [4.2 实现要点解析](#4.2 实现要点解析)
- [五、Hidden 与 None 的选型建议](#五、Hidden 与 None 的选型建议)
- [六、与 opacity 的区别](#六、与 opacity 的区别)
- 七、完整示例代码
- 八、总结
一、属性签名与参数说明
typescript
visibility(value: Visibility): T
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
value |
Visibility |
是 | Visibility.Visible |
设置组件的可见性 |
Visibility 枚举定义:
typescript
enum Visibility {
Visible, // 正常显示,组件参与布局(默认值)
Hidden, // 组件不可见,但仍占据布局空间
None // 组件不可见,且不占据布局空间
}
二、三个枚举值的核心区别
| 枚举值 | 是否可见 | 是否占据布局空间 | 类比 CSS |
|---|---|---|---|
Visibility.Visible |
✅ 可见 | ✅ 占位 | visibility: visible |
Visibility.Hidden |
❌ 不可见 | ✅ 占位 | visibility: hidden |
Visibility.None |
❌ 不可见 | ❌ 不占位 | display: none |
关键区别 :
Hidden和None都让组件不可见,但Hidden保留布局空间,None完全从布局中移除。这一区别对页面排版影响显著。
三、示例一:三种枚举值的直观对比
3.1 代码
typescript
Column({ space: 4 }) {
// 参照行:始终可见,用于对比布局占位差异
Text('参照行(始终 Visible)')
.width('90%').height(50)
.fontSize(14).textAlign(TextAlign.Center)
.backgroundColor('#4CAF50').fontColor(Color.White).borderRadius(6)
// Hidden:不可见但占位,上下间距与 Visible 完全相同
Text('Hidden(不可见,占位)')
.width('90%').height(50)
.fontSize(14).textAlign(TextAlign.Center)
.backgroundColor('#FF9800').fontColor(Color.White).borderRadius(6)
.visibility(Visibility.Hidden)
// None:不可见且不占位,两侧行之间间距被压缩
Text('None(不可见,不占位)')
.width('90%').height(50)
.fontSize(14).textAlign(TextAlign.Center)
.backgroundColor('#F44336').fontColor(Color.White).borderRadius(6)
.visibility(Visibility.None)
// 参照行:始终可见
Text('参照行(始终 Visible)')
.width('90%').height(50)
.fontSize(14).textAlign(TextAlign.Center)
.backgroundColor('#4CAF50').fontColor(Color.White).borderRadius(6)
}
.width('90%').padding(12)
.border({ width: 1, color: '#CCCCCC' }).borderRadius(8)
3.2 布局效果分析
代码中用两行绿色"参照行"夹住橙色(Hidden)和红色(None)组件,运行后可直观看到:
┌─────────────────────────────┐
│ 参照行(始终 Visible)绿 │ ← 可见,占位
│ │ ← Hidden 的位置:不可见,但有 50px 高度占位
│ 参照行(始终 Visible)绿 │ ← 可见,占位(None 已消失,两行紧邻)
└─────────────────────────────┘
Hidden效果:橙色文本不可见,但两个绿色参照行之间存在 50px 的空白间距,说明它仍然占位。None效果:红色文本不可见,且两个绿色参照行之间没有额外空白,说明它已完全脱离布局。
四、示例二:动态切换 visibility
4.1 代码
typescript
@Entry
@Component
struct VisibilityExample {
@State visibilityValue: Visibility = Visibility.Visible;
build() {
Column({ space: 8 }) {
// 受控组件:visibility 由状态变量驱动
Text(`当前状态:${this.visibilityValue === Visibility.Visible ? 'Visible' :
this.visibilityValue === Visibility.Hidden ? 'Hidden' : 'None'}`)
.width('90%').height(60)
.fontSize(15).textAlign(TextAlign.Center)
.backgroundColor('#2196F3').fontColor(Color.White).borderRadius(8)
.visibility(this.visibilityValue) // ← 绑定状态变量
// 切换按钮行
Row({ space: 12 }) {
Button('Visible')
.onClick(() => { this.visibilityValue = Visibility.Visible; })
.backgroundColor('#4CAF50').fontColor(Color.White)
.borderRadius(6).height(40).layoutWeight(1)
Button('Hidden')
.onClick(() => { this.visibilityValue = Visibility.Hidden; })
.backgroundColor('#FF9800').fontColor(Color.White)
.borderRadius(6).height(40).layoutWeight(1)
Button('None')
.onClick(() => { this.visibilityValue = Visibility.None; })
.backgroundColor('#F44336').fontColor(Color.White)
.borderRadius(6).height(40).layoutWeight(1)
}.width('90%')
Text('↑ 切换为 Hidden 时上方色块占位但不可见;切换为 None 时色块消失且不占位')
.width('90%').fontSize(12).fontColor('#999999')
.textAlign(TextAlign.Center)
}
}
}
运行效果:

4.2 实现要点解析
① @State 驱动 visibility
typescript
@State visibilityValue: Visibility = Visibility.Visible;
将 Visibility 枚举值存入状态变量,组件的 .visibility(this.visibilityValue) 随状态自动响应刷新。这是 ArkUI 数据驱动 UI 的标准写法。
② .visibility() 绑定状态变量
typescript
Text(...)
.visibility(this.visibilityValue)
与静态写法 .visibility(Visibility.Hidden) 不同,这里传入的是状态变量,实现了运行时动态控制。任何触发状态变量变化的操作(按钮点击、网络回调、定时器等)都会立即更新组件的可见性。
③ 三元表达式生成提示文字
typescript
Text(`当前状态:${this.visibilityValue === Visibility.Visible ? 'Visible' :
this.visibilityValue === Visibility.Hidden ? 'Hidden' : 'None'}`)
注意:这段文字本身也受 .visibility(this.visibilityValue) 控制。当切换为 Hidden 或 None 时,文字也会随之隐藏------这正好演示了 visibility 对组件自身内容的作用范围。
五、Hidden 与 None 的选型建议
两者都能隐藏组件,选择哪个取决于隐藏后是否需要保留布局空间:
| 场景 | 推荐 | 原因 |
|---|---|---|
| 加载中占位(skeleton 效果) | Hidden |
保持布局稳定,加载完成后直接显示,不引起页面跳动 |
| 权限控制(无权限则不显示) | None |
无权限时不应占用空间,避免出现莫名空白 |
| 表单字段条件显示/隐藏 | None |
隐藏后后续字段自动上移,布局更紧凑 |
| 动画过渡前的预占位 | Hidden |
动画开始前保留位置,防止其他元素位移 |
| Tab 切换内容面板 | 视需求 | 需要保持滚动位置用 Hidden;需要释放空间用 None |
六、与 opacity 的区别
初学者容易混淆 visibility 与 opacity,两者都能让组件"不可见",但行为不同:
| 属性 | 隐藏方式 | 是否占位 | 是否响应事件 |
|---|---|---|---|
.visibility(Visibility.Hidden) |
不渲染像素 | ✅ 占位 | ❌ 不响应 |
.visibility(Visibility.None) |
脱离布局 | ❌ 不占位 | ❌ 不响应 |
.opacity(0) |
透明度为 0 | ✅ 占位 | ✅ 仍响应点击 |
如果需要"看不见但仍可点击",用
.opacity(0);如果需要"看不见且不可点击",用.visibility(Visibility.Hidden)或.visibility(Visibility.None)。
七、完整示例代码
以下是 index.ets 中的完整代码,包含两个演示区块:
typescript
// xxx.ets
// Visibility 枚举值说明:
// Visible ------ 正常显示,组件参与布局(默认值)
// Hidden ------ 组件不可见,但仍占据布局空间
// None ------ 组件不可见,且不占据布局空间(等同于 display:none)
@Entry
@Component
struct VisibilityExample {
@State visibilityValue: Visibility = Visibility.Visible;
build() {
Column({ space: 20 }) {
// ── 一、三种枚举值的直观对比 ──────────────────────────────────────────
Text('三种枚举值对比').fontSize(16).fontWeight(FontWeight.Bold).width('90%')
Column({ space: 4 }) {
Text('参照行(始终 Visible)')
.width('90%').height(50)
.fontSize(14).textAlign(TextAlign.Center)
.backgroundColor('#4CAF50').fontColor(Color.White).borderRadius(6)
Text('Hidden(不可见,占位)')
.width('90%').height(50)
.fontSize(14).textAlign(TextAlign.Center)
.backgroundColor('#FF9800').fontColor(Color.White).borderRadius(6)
.visibility(Visibility.Hidden)
Text('None(不可见,不占位)')
.width('90%').height(50)
.fontSize(14).textAlign(TextAlign.Center)
.backgroundColor('#F44336').fontColor(Color.White).borderRadius(6)
.visibility(Visibility.None)
Text('参照行(始终 Visible)')
.width('90%').height(50)
.fontSize(14).textAlign(TextAlign.Center)
.backgroundColor('#4CAF50').fontColor(Color.White).borderRadius(6)
}
.width('90%').padding(12)
.border({ width: 1, color: '#CCCCCC' }).borderRadius(8)
// ── 二、动态切换 visibility ────────────────────────────────────────────
Text('动态切换示例').fontSize(16).fontWeight(FontWeight.Bold).width('90%')
Column({ space: 8 }) {
Text(`当前状态:${this.visibilityValue === Visibility.Visible ? 'Visible' :
this.visibilityValue === Visibility.Hidden ? 'Hidden' : 'None'}`)
.width('90%').height(60)
.fontSize(15).textAlign(TextAlign.Center)
.backgroundColor('#2196F3').fontColor(Color.White).borderRadius(8)
.visibility(this.visibilityValue)
Row({ space: 12 }) {
Button('Visible')
.onClick(() => { this.visibilityValue = Visibility.Visible; })
.backgroundColor('#4CAF50').fontColor(Color.White)
.borderRadius(6).height(40).layoutWeight(1)
Button('Hidden')
.onClick(() => { this.visibilityValue = Visibility.Hidden; })
.backgroundColor('#FF9800').fontColor(Color.White)
.borderRadius(6).height(40).layoutWeight(1)
Button('None')
.onClick(() => { this.visibilityValue = Visibility.None; })
.backgroundColor('#F44336').fontColor(Color.White)
.borderRadius(6).height(40).layoutWeight(1)
}.width('90%')
Text('↑ 切换为 Hidden 时上方色块占位但不可见;切换为 None 时色块消失且不占位')
.width('90%').fontSize(12).fontColor('#999999')
.textAlign(TextAlign.Center)
}
.width('90%').padding(12)
.border({ width: 1, color: '#CCCCCC' }).borderRadius(8)
}
.width('100%').height('100%')
.padding({ top: 20, bottom: 20 })
.backgroundColor('#F5F5F5')
}
}
运行结果:

八、总结
| 要点 | 说明 |
|---|---|
| 函数签名 | visibility(value: Visibility): T,链式调用 |
| 默认值 | Visibility.Visible,不设置时组件正常显示 |
Hidden vs None |
都不可见;Hidden 占位,None 不占位 |
Hidden vs opacity(0) |
都占位且不可见;Hidden 不响应事件,opacity(0) 仍响应 |
| 动态控制 | 配合 @State 变量,实现运行时响应式切换 |
| 适用组件 | 所有 ArkUI 组件均支持 .visibility() 通用属性 |
如果这篇文章对你有帮助,欢迎点赞、收藏、关注,你的支持是持续创作的动力!