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

Flutter中Snackbar为何同时显示在Dialog内部及Dialog后方

问题原因

你遇到的Snackbar同时在Dialog和主屏幕展示的问题,本质是ScaffoldMessenger的作用域问题:Flutter默认由根MaterialApp提供全局的ScaffoldMessenger实例,你在Dialog内部调用ScaffoldMessenger.of(context)时,默认匹配到的是这个全局实例,会将Snackbar挂载到全局Scaffold层,就出现了两处同时展示的问题。你之前尝试的GlobalKey、Builder等方案都是解决「找不到Scaffold」的场景,自然不匹配当前问题。

解决方案

只需要给Dialog内部的UserPage外层套一个独立的局部ScaffoldMessenger,让内部的Snackbar请求优先匹配局部实例,就只会在Dialog内部的Scaffold上展示Snackbar。

修改user_page.dart的build方法即可:

import 'package:flutter/material.dart';

class UserPage extends StatefulWidget {

  @override
  _UserPageState createState() => _UserPageState();
}

class _UserPageState extends State<UserPage> {
  @override
  Widget build(BuildContext context) {
    print('_UserPageState _showUser context: ${context.hashCode}');
    // 新增局部ScaffoldMessenger包裹原有Scaffold
    return ScaffoldMessenger(
      child: Scaffold(
        appBar: AppBar(
          title: Text('User Account'),
          actions: <Widget>[
            MaterialButton(
              onPressed: () => _save(),
              child: Text(
                'Save',
                style: TextStyle(color: Colors.white),
              ),
            ),
          ],
        ),
        body: Text('Dialog Body'),
      ),
    );
  }


  void _save() async {
    print('_UserPageState _save context: ${context.hashCode}');
    try {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('Something updated.'),
          backgroundColor: Colors.green,
        ),
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
            content: Text('Save failed: ${e.toString()}'),
            backgroundColor: Colors.red),
      );
    }
  }
}

修改完成后重新运行,点击Save按钮就只会在Dialog底部展示Snackbar,主屏幕不会再出现重复的Snackbar。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 10:57:02