在这里插入图片描述

案例概述

Visibility 是 Flutter 中用于控制子组件显示/隐藏的组件。与简单的条件判断不同,Visibility 提供了多种隐藏方式,包括完全移除、保留空间、替换为占位符等。本案例展示了如何使用 Visibility 创建各种可见性控制效果。

核心概念

1. 可见性控制方式

Visibility 提供了三种隐藏方式:visible(显示)、hidden(隐藏但保留空间)、gone(隐藏并移除空间)。不同的方式适合不同的场景,如表单验证提示、条件渲染等。

2. 替换组件

Visibility 支持通过 replacement 参数指定隐藏时显示的替代组件。这种方式适合需要显示占位符或加载指示器的场景。

3. 动画可见性

Visibility 可以与 AnimatedOpacity 结合创建平滑的显示/隐藏动画效果。

代码详解

示例 1:基础可见性控制

class BasicVisibilityExample extends StatefulWidget {
  
  State<BasicVisibilityExample> createState() => _BasicVisibilityExampleState();
}

class _BasicVisibilityExampleState extends State<BasicVisibilityExample> {
  bool _isVisible = true;

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        Visibility(
          visible: _isVisible,
          child: Container(
            color: Colors.blue,
            height: 100,
            child: const Center(child: Text('可见内容')),
          ),
        ),
        ElevatedButton(
          onPressed: () {
            setState(() {
              _isVisible = !_isVisible;
            });
          },
          child: const Text('切换可见性'),
        ),
      ],
    );
  }
}

代码解释: 这个示例展示了 Visibility 的基础用法。通过 visible 参数控制子组件是否显示。当 visible 为 false 时,子组件完全移除。这种方式适合简单的显示/隐藏场景。

示例 2:保留空间隐藏

class HiddenWithSpaceExample extends StatefulWidget {
  
  State<HiddenWithSpaceExample> createState() => _HiddenWithSpaceExampleState();
}

class _HiddenWithSpaceExampleState extends State<HiddenWithSpaceExample> {
  bool _isVisible = true;

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        Visibility(
          visible: _isVisible,
          maintainSize: true,
          maintainAnimation: true,
          maintainState: true,
          child: Container(
            color: Colors.green,
            height: 100,
            child: const Center(child: Text('隐藏但保留空间')),
          ),
        ),
        ElevatedButton(
          onPressed: () {
            setState(() {
              _isVisible = !_isVisible;
            });
          },
          child: const Text('切换可见性'),
        ),
      ],
    );
  }
}

代码解释: 这个示例展示了如何使用 maintainSize、maintainAnimation、maintainState 参数保留隐藏组件的空间。这种方式适合需要保持布局稳定的场景,如表单中的条件字段。

示例 3:替换为占位符

class ReplacementExample extends StatefulWidget {
  
  State<ReplacementExample> createState() => _ReplacementExampleState();
}

class _ReplacementExampleState extends State<ReplacementExample> {
  bool _isVisible = true;

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        Visibility(
          visible: _isVisible,
          replacement: Container(
            color: Colors.grey,
            height: 100,
            child: const Center(child: Text('加载中...')),
          ),
          child: Container(
            color: Colors.orange,
            height: 100,
            child: const Center(child: Text('内容已加载')),
          ),
        ),
        ElevatedButton(
          onPressed: () {
            setState(() {
              _isVisible = !_isVisible;
            });
          },
          child: const Text('切换内容'),
        ),
      ],
    );
  }
}

代码解释: 这个示例展示了如何使用 replacement 参数指定隐藏时显示的替代组件。这种方式适合加载状态、错误提示等场景。

示例 4:条件渲染列表

class ConditionalListExample extends StatefulWidget {
  
  State<ConditionalListExample> createState() => _ConditionalListExampleState();
}

class _ConditionalListExampleState extends State<ConditionalListExample> {
  final List<String> items = ['项目1', '项目2', '项目3'];
  final Set<int> visibleItems = {0, 1, 2};

  
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: items.length,
      itemBuilder: (context, index) {
        return Visibility(
          visible: visibleItems.contains(index),
          child: ListTile(
            title: Text(items[index]),
            trailing: IconButton(
              icon: const Icon(Icons.delete),
              onPressed: () {
                setState(() {
                  visibleItems.remove(index);
                });
              },
            ),
          ),
        );
      },
    );
  }
}

代码解释: 这个示例展示了如何在列表中使用 Visibility 实现条件渲染。通过维护一个可见项目的集合,可以动态控制列表项的显示/隐藏。

示例 5:动画可见性

class AnimatedVisibilityExample extends StatefulWidget {
  
  State<AnimatedVisibilityExample> createState() => _AnimatedVisibilityExampleState();
}

class _AnimatedVisibilityExampleState extends State<AnimatedVisibilityExample> {
  bool _isVisible = true;

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        AnimatedOpacity(
          opacity: _isVisible ? 1.0 : 0.0,
          duration: const Duration(milliseconds: 300),
          child: Visibility(
            visible: _isVisible,
            child: Container(
              color: Colors.purple,
              height: 100,
              child: const Center(child: Text('动画可见性')),
            ),
          ),
        ),
        ElevatedButton(
          onPressed: () {
            setState(() {
              _isVisible = !_isVisible;
            });
          },
          child: const Text('切换可见性'),
        ),
      ],
    );
  }
}

代码解释: 这个示例展示了如何结合 AnimatedOpacity 创建平滑的显示/隐藏动画。通过动画效果,可以提升用户体验。

高级话题

1. 动态/响应式设计

根据屏幕大小动态控制组件的可见性。

2. 动画与过渡

使用 AnimatedOpacity、AnimatedContainer 等创建平滑的过渡效果。

3. 搜索/过滤/排序

根据搜索结果动态控制列表项的可见性。

4. 选择与批量操作

支持选择和隐藏多个项目。

5. 加载与缓存

在加载时显示占位符,加载完成后显示内容。

6. 键盘导航

支持键盘快捷键控制可见性。

7. 无障碍支持

通过 Semantics 提供无障碍支持。

8. 样式自定义

根据可见性状态动态改变样式。

9. 数据持久化/导出

保存可见性状态到本地存储。

10. 单元测试与集成测试

测试可见性控制的逻辑。

PC 端适配要点

  • 根据屏幕宽度调整可见性规则
  • 支持键盘快捷键切换可见性
  • 提供清晰的可见性指示

实际应用场景

  • 表单验证提示:条件显示错误消息
  • 权限控制:根据权限显示/隐藏功能
  • 加载状态:显示加载指示器或内容
  • 搜索过滤:根据搜索结果显示/隐藏项目

扩展建议

  • 学习高级的条件渲染模式
  • 研究性能优化技巧
  • 探索与其他组件的组合
  • 集成状态管理库

总结

Visibility 是控制组件显示/隐藏的强大工具。通过灵活使用 Visibility 的不同参数,可以创建各种可见性控制效果。理解不同的隐藏方式和应用场景是关键。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐