想用flutter web构建抽屉。但是在小部件树中检测到 Duplicate GlobalKey。实例被移动到新位置。关键是:
- [LabeledGlobalKey#c9754]
GlobalKey reparenting 是:
-
MainScreen(dependencies: [MediaQuery], state: _MainScreenState#dc897) 在小部件树中一次只能在一个小部件上指定 GlobalKey。
import 'package:flutter/material.dart'; class MenuController with ChangeNotifier { GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); GlobalKey<ScaffoldState> get scaffoldKey => _scaffoldKey; void controlMenu() { if (!_scaffoldKey.currentState!.isDrawerOpen) { _scaffoldKey.currentState!.openDrawer(); } } // void disposeKey() { // _scaffoldKey.currentState.(); // } } class _MainScreenState extends State<MainScreen> { @override void initState() { print('init CALLED- GAME---'); super.initState(); } @override void dispose() { print('DISPOSE CALLED- GAME---'); context.read<MenuController>().scaffoldKey.currentState!.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( key: context.read<MenuController>().scaffoldKey, drawer: SideMenu(), body: SafeArea( child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ // We want this side menu only for large screen if (Responsive.isDesktop(context)) Expanded( // default flex = 1 // and it takes 1/6 part of the screen child: SideMenu(), ), Expanded( // It takes 5/6 part of the screen flex: 5, child: DashboardScreen(), ), ], ), ), ); }}
然后想重用另一个小部件的密钥
class ProductsScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
key: context.read<MenuController>().scaffoldKey,
drawer: SideMenu(),
body: SafeArea(
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// We want this side menu only for large screen
if (Responsive.isDesktop(context))
Expanded(
// default flex = 1
// and it takes 1/6 part of the screen
child: SideMenu(),
),
Expanded(
// It takes 5/6 part of the screen
flex: 5,
child: ProductsListScreen(),
),
],
),
),
);
}
}
并得到了错误
要在 SideMenu 小部件中导航,请使用
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => ProductsScreen(),
),
);
您不需要手动处理
GlobalKey
。主要要求是它们不能两次插入到小部件树中。其他键(LocalKey
s)不是这种情况:违反这一点的一个常见原因是动画。在播放一个页面和另一个页面之间的动画时,两个页面都在小部件树中,如果它们具有相同的
GlobalKey
,则会引发错误。调用
globalKey.currentState!.dispose()
实际上会处理关联小部件的State
。您不应该自己调用它。相反,为第二个子树提供一个新的
GlobalKey
或在导航到新页面之前删除旧的。