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

Flutter中实现ExpansionTile展开/收起时切换标题

Flutter ExpansionTile 切换标题文本(展开显示"less",收起显示"more")

错误原因

你碰到的Failed assertion: line 49 pos 12: '_state != null': is not true错误,是因为直接调用ExpansionTileController.isExpanded时,控制器还没和ExpansionTile的内部状态完成绑定,此时控制器的_state属性为null,触发了断言检查失败。

解决方案一:用onExpansionChanged回调维护状态(无需额外控制器)

这种方式更简洁,直接通过ExpansionTile自带的回调来更新本地状态,从而切换标题文本:

class ToggleTitleExpansionTile extends StatefulWidget {
  const ToggleTitleExpansionTile({super.key});

  @override
  State<ToggleTitleExpansionTile> createState() => _ToggleTitleExpansionTileState();
}

class _ToggleTitleExpansionTileState extends State<ToggleTitleExpansionTile> {
  bool _isExpanded = false;

  @override
  Widget build(BuildContext context) {
    return ExpansionTile(
      title: Text(_isExpanded ? 'less' : 'more'),
      onExpansionChanged: (expanded) {
        setState(() {
          _isExpanded = expanded;
        });
      },
      children: const [
        // 这里放展开后的内容
        Padding(
          padding: EdgeInsets.all(16.0),
          child: Text('展开后的内容'),
        ),
      ],
    );
  }
}

解决方案二:使用ExpansionTileController(适合需要主动控制展开/收起的场景)

如果必须用控制器,需要确保控制器正确绑定到ExpansionTile,并且通过监听状态变化来更新UI:

class ControllerToggleExpansionTile extends StatefulWidget {
  const ControllerToggleExpansionTile({super.key});

  @override
  State<ControllerToggleExpansionTile> createState() => _ControllerToggleExpansionTileState();
}

class _ControllerToggleExpansionTileState extends State<ControllerToggleExpansionTile> {
  late final ExpansionTileController _controller;
  bool _isExpanded = false;

  @override
  void initState() {
    super.initState();
    _controller = ExpansionTileController();
    // 监听控制器的展开状态变化
    _controller.addListener(() {
      setState(() {
        _isExpanded = _controller.isExpanded;
      });
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ExpansionTile(
      controller: _controller,
      title: Text(_isExpanded ? 'less' : 'more'),
      children: const [
        Padding(
          padding: EdgeInsets.all(16.0),
          child: Text('展开后的内容'),
        ),
      ],
    );
  }
}

注意事项

  • 不要在控制器未绑定到ExpansionTile时直接访问isExpanded,这是导致你报错的核心原因。
  • 如果用控制器,一定要在initState中初始化,并在dispose中释放资源,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 21:59:56