You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter:如何用Stack动态构建组件替代Visibility实现显隐

移除Visibility组件,动态构建选项菜单

作为Flutter新手,我目前用Visibility组件来显示/隐藏选项菜单,但知道这种方式不是最优解。现在想移除Visibility,改成点击按钮时在Stack中动态构建选项菜单,选择选项后菜单消失并更新按钮的显示文本。

当前代码已实现点击按钮显示菜单、选择后更新文本并隐藏菜单的逻辑,需调整组件构建方式以替换Visibility。


修改后的TestPage代码

class TestPage extends StatefulWidget {
  const TestPage({Key? key}) : super(key: key);

  @override
  State<TestPage> createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  String displayText = 'Choose option';
  bool showMenu = false; // 变量名优化为更贴合语义的表述

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          Center(
            child: Column(
              children: [
                const SizedBox(height: 50),
                InkWell(
                  onTap: () {
                    setState(() => showMenu = true);
                  },
                  child: Container(
                    height: 40,
                    width: 100,
                    color: Colors.yellow,
                    child: Center(
                      child: Text(
                        displayText,
                        style: const TextStyle(color: Colors.black),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
          // 条件性插入菜单组件:仅当showMenu为true时才将其加入Widget树
          if (showMenu)
            OptionMenu(
              onTap: (val) {
                setState(() {
                  displayText = val;
                  showMenu = false;
                });
              },
            ),
        ],
      ),
    );
  }
}

关键调整说明

  • 移除Visibility组件,改用条件性Widget插入:在Stack的children列表中通过if (showMenu)判断,仅在需要显示菜单时才构建OptionMenu,彻底避免了隐藏状态下组件仍存在于Widget树的问题,性能更优。
  • 原OptionMenu和Button组件无需修改,保持原有交互逻辑即可。

原参考代码(无需修改)

OptionMenu代码

class OptionMenu extends StatelessWidget {
  OptionMenu({required this.onTap});
  final ValueChanged? onTap;
  
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        children: [
          const SizedBox(height: 50),
          Button(text: 'Option A', onTap: onTap),
          const SizedBox(height: 5),
          Button(text: 'Option B', onTap: onTap),
          const SizedBox(height: 5),
          Button(text: 'Option C', onTap: onTap),
          const SizedBox(height: 5),
          Button(text: 'Option D', onTap: onTap),
          const SizedBox(height: 5),
        ],
      ),
    );
  }
}

Button代码

class Button extends StatelessWidget {
  Button({required this.text, required this.onTap});
  final String text;
  final ValueChanged? onTap;
  
  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {
        onTap?.call(text);
      },
      child: Container(
        height: 40,
        width: 100,
        color: Colors.yellow,
        child: Center(
          child: Text(
            text,
            style: const TextStyle(color: Colors.black),
          ),
        ),
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者Nomad09

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 10:55:17