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

Flutter中如何点击TextButton后显示包含Card的ListView

问题解决说明

现有代码核心问题

  • 你定义的getCard()返回的ListView组件没有被加入到build方法的Widget渲染树中,就算触发setState也不会显示
  • 仅用buttonClicked布尔值无法区分点击的是哪个分类按钮,不能匹配对应分类的列表内容
  • 根布局结构错误,没有预留列表的展示位置

解决方案

  1. 把状态变量从bool buttonClicked改成存储当前选中的分类索引的int? selectedTabIndex,默认值为null代表未选中任何分类
  2. 调整body的根布局为Column,先放顶部分类按钮栏,再根据selectedTabIndex的值判断是否展示对应列表
  3. 每个分类按钮点击时更新选中的索引值,同时新增按钮选中态样式优化体验
  4. 根据选中的索引加载对应分类的列表数据

修改后完整代码

class _CardScreenState extends State<CardScreen> {
  // 存储当前选中的分类索引,null代表未选中
  int? selectedTabIndex;
  // 分类名称列表
  List<String> tabTitles = [
    "On hold",
    "In progress",
    "Needs review",
    "Approved",
  ];
  // 模拟每个分类对应的列表数据,可根据实际需求替换
  Map<int, List<String>> tabListData = {
    0: ["待处理任务1", "待处理任务2", "待处理任务3"],
    1: ["进行中任务1", "进行中任务2"],
    2: ["待审核任务1", "待审核任务2", "待审核任务3", "待审核任务4"],
    3: ["已通过任务1"],
  };

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButtonLocation: FloatingActionButtonLocation.endTop,
      floatingActionButton: FloatingActionButton(
        backgroundColor: Colors.tealAccent,
        onPressed: () {
          Get.back();
        },
        child: const Icon(Icons.arrow_back),
      ),
      body: Container(
        color: Colors.black,
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.height,
        alignment: Alignment.topCenter,
        // 改为Column布局,先放顶部按钮栏,再放列表
        child: Column(
          children: [
            // 原有的顶部分类按钮栏
            SizedBox(
              height: 150,
              width: 500,
              child: DecoratedBox(
                decoration: BoxDecoration(color: Colors.grey[900]),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: List.generate(tabTitles.length, (index) {
                    // 批量生成分类按钮,减少重复代码
                    bool isSelected = selectedTabIndex == index;
                    return Expanded(
                      child: TextButton(
                        onPressed: () {
                          setState(() {
                            // 如果点击的是已选中的按钮,可以关闭列表,也可以保留,按需调整
                            selectedTabIndex = isSelected ? null : index;
                          });
                        },
                        child: Text(
                          tabTitles[index],
                          style: TextStyle(
                            // 选中的按钮文字高亮
                            color: isSelected ? Colors.tealAccent : Colors.grey[300],
                          ),
                        ),
                      ),
                    );
                  }),
                ),
              ),
            ),
            // 选中分类后展示对应列表
            if (selectedTabIndex != null)
              getCard(selectedTabIndex!)
          ],
        ),
      ),
    );
  }

  // 根据传入的分类索引加载对应列表
  Widget getCard(int tabIndex) {
    final list = tabListData[tabIndex] ?? [];
    return Expanded(
      child: ListView.builder(
        padding: const EdgeInsets.all(16),
        itemCount: list.length,
        itemBuilder: (_, index) => Card(
          color: Colors.grey,
          margin: const EdgeInsets.only(bottom: 12),
          child: Padding(
            padding: const EdgeInsets.all(16),
            child: Text(list[index]),
          ),
        ),
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 04:36:04