想要用flutter web构建抽屉。但是得到了在小部件树中检测到重复的GlobalKey。实例移动到新位置。关键是:
- [LabeledGlobalKey#c9754]
全局密钥重排序为:
- 主屏幕(依赖项:[MediaQuery],状态:_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(并非如此:
// this is allowed
Row(
children: [
SizedBox(key: Key('hello')),
Container(key: Key('hello')),
],
)
// this is not
final key = GlobalKey<ScaffoldState>();
Row(
children: [
Scaffold(key: key),
Scaffold(key: key),
],
)
违反这一规定的一个常见原因是动画。当播放一个页面和另一个页面之间的动画时,两个页面都在小部件树中,如果它们具有相同的GlobalKey
,则会引发错误。
调用CCD_ 4实际上是对关联小部件的CCD_。你不应该自己这么说。
相反,在导航到新页面之前,向第二个子树提供一个新的GlobalKey
或删除旧的。