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

Flutter自定义NavBar中GestureDetector点击Container无响应问题排查

问题原因及修复方案

核心问题

你的_isMapsSelected变量定义在build()方法内部,每次调用setState()都会重新执行build,这会把变量重新初始化为true——也就是说你点击"Discover"修改状态后,立刻又被重置回去了,所以看起来手势没生效。

修复步骤

把状态变量移到State类的成员位置,确保它不会在build时被反复初始化:

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

  @override
  State<SearchPage> createState() => _SearchPageState();
}

class _SearchPageState extends State<SearchPage> {
  // 将变量移至此处,作为State类的成员变量
  bool _isMapsSelected = true;

  @override
  Widget build(BuildContext context) {
    // 移除原build方法内的bool _isMapsSelected = true;

    return Scaffold(
      extendBodyBehindAppBar: true,
      backgroundColor: Colors.grey,
      appBar: AppBar(
        elevation: 0,
        backgroundColor: Colors.transparent,
        title: ClipRRect(
            borderRadius: const BorderRadius.only(
                topLeft: Radius.circular(FizzinConstants.radius),
                topRight: Radius.circular(FizzinConstants.radius)),
            child: BackdropFilter(
                filter: ImageFilter.blur(
                  sigmaX: 15.0,
                  sigmaY: 25.0,
                ),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: [
                    GestureDetector(
                      behavior: HitTestBehavior.translucent,
                      onTap: () => {
                        setState(() {
                          _isMapsSelected = true;
                        })
                      },
                      child: Container(
                        padding: const EdgeInsets.all(10),
                        decoration: BoxDecoration(
                          borderRadius:
                              BorderRadius.circular(FizzinConstants.radius),
                          color: _isMapsSelected
                              ? FizzinColors.cVividBlue
                              : Colors.transparent,
                        ),
                        child: Text(
                          'Maps',
                          style: _isMapsSelected
                              ? const TextStyle(
                                  color: Colors.white,
                                  fontSize: 16,
                                  fontWeight: FontWeight.bold)
                              : const TextStyle(
                                  color: FizzinColors.cDarkGrey,
                                  fontSize: 14,
                                  fontWeight: FontWeight.bold),
                        ),
                      ),
                    ),
                    GestureDetector(
                        behavior: HitTestBehavior.translucent,
                        onTap: () => {
                              setState(() {
                                _isMapsSelected = false;
                              })
                            },
                        child: Container(
                          padding: const EdgeInsets.all(10),
                          decoration: BoxDecoration(
                            borderRadius:
                                BorderRadius.circular(FizzinConstants.radius),
                            color: _isMapsSelected
                                ? Colors.transparent
                                : FizzinColors.cVividBlue,
                          ),
                          child: Text(
                            'Discover',
                            style: _isMapsSelected
                                ? const TextStyle(
                                    color: FizzinColors.cDarkGrey,
                                    fontSize: 14,
                                    fontWeight: FontWeight.bold)
                                : const TextStyle(
                                    color: Colors.white,
                                    fontSize: 16,
                                    fontWeight: FontWeight.bold),
                          ),
                        )),
                  ],
                ))),
      ),
      body: _isMapsSelected ? const MapContentTab() : const SearchContentTab(),
    );
  }
}

额外说明

  • 之前使用AbsorbPointer完全没必要,问题根本不是手势被拦截,而是状态变量的作用域错误。
  • 状态变量必须放在State类的成员区域,才能在多次build调用之间保持状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:42:27