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
相关产品推荐
相关产品推荐

