我看到这个错误在过去的3-4天**“多个小部件使用相同的GlobalKey。"**。我一直在尝试建立一个网页与PageView。builder和当我的网页到达商店图片部分我的代码抛出这个异常。
======== Exception caught by widgets library =======================================================
The following assertion was thrown while finalizing the widget tree:
Multiple widgets used the same GlobalKey.
The key [LabeledGlobalKey<FormState>#5908a] was used by multiple widgets. The parents of those widgets were different widgets that both had the following description:
Expanded(flex: 1)
A GlobalKey can only be specified on one widget at a time in the widget tree.
When the exception was thrown, this was the stack:
#0 BuildOwner._debugVerifyGlobalKeyReservation.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:flutter/src/widgets/framework.dart:2883:13)
#1 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617:13)
#2 BuildOwner._debugVerifyGlobalKeyReservation.<anonymous closure>.<anonymous closure> (package:flutter/src/widgets/framework.dart:2827:20)
#3 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617:13)
#4 BuildOwner._debugVerifyGlobalKeyReservation.<anonymous closure> (package:flutter/src/widgets/framework.dart:2822:36)
#5 BuildOwner._debugVerifyGlobalKeyReservation (package:flutter/src/widgets/framework.dart:2891:6)
#6 BuildOwner.finalizeTree.<anonymous closure> (package:flutter/src/widgets/framework.dart:2950:11)
#7 BuildOwner.finalizeTree (package:flutter/src/widgets/framework.dart:3032:8)
#8 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:885:19)
#9 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:378:5)
#10 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1175:15)
#11 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1104:9)
#12 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1015:5)
#16 _invoke (dart:ui/hooks.dart:150:10)
#17 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:318:5)
#18 _drawFrame (dart:ui/hooks.dart:115:31)
(elided 3 frames from dart:async)
====================================================================================================
======== Exception caught by widgets library =======================================================
The following assertion was thrown while finalizing the widget tree:
Multiple widgets used the same GlobalKey.
The key [LabeledGlobalKey<FormState>#5908a] was used by multiple widgets. The parents of those widgets were different widgets that both had the following description:
Expanded(flex: 1)
A GlobalKey can only be specified on one widget at a time in the widget tree.
When the exception was thrown, this was the stack:
#0 BuildOwner._debugVerifyGlobalKeyReservation.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:flutter/src/widgets/framework.dart:2883:13)
#1 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617:13)
#2 BuildOwner._debugVerifyGlobalKeyReservation.<anonymous closure>.<anonymous closure> (package:flutter/src/widgets/framework.dart:2827:20)
#3 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617:13)
#4 BuildOwner._debugVerifyGlobalKeyReservation.<anonymous closure> (package:flutter/src/widgets/framework.dart:2822:36)
#5 BuildOwner._debugVerifyGlobalKeyReservation (package:flutter/src/widgets/framework.dart:2891:6)
#6 BuildOwner.finalizeTree.<anonymous closure> (package:flutter/src/widgets/framework.dart:2950:11)
#7 BuildOwner.finalizeTree (package:flutter/src/widgets/framework.dart:3032:8)
#8 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:885:19)
#9 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:378:5)
#10 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1175:15)
#11 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1104:9)
#12 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1015:5)
#16 _invoke (dart:ui/hooks.dart:150:10)
#17 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:318:5)
#18 _drawFrame (dart:ui/hooks.dart:115:31)
(elided 3 frames from dart:async)
====================================================================================================
======== Exception caught by widgets library =======================================================
The following assertion was thrown while finalizing the widget tree:
Multiple widgets used the same GlobalKey.
The key [LabeledGlobalKey<FormState>#5908a] was used by multiple widgets. The parents of those widgets were different widgets that both had the following description:
Expanded(flex: 1)
A GlobalKey can only be specified on one widget at a time in the widget tree.
When the exception was thrown, this was the stack:
#0 BuildOwner._debugVerifyGlobalKeyReservation.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:flutter/src/widgets/framework.dart:2883:13)
#1 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617:13)
#2 BuildOwner._debugVerifyGlobalKeyReservation.<anonymous closure>.<anonymous closure> (package:flutter/src/widgets/framework.dart:2827:20)
#3 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617:13)
#4 BuildOwner._debugVerifyGlobalKeyReservation.<anonymous closure> (package:flutter/src/widgets/framework.dart:2822:36)
#5 BuildOwner._debugVerifyGlobalKeyReservation (package:flutter/src/widgets/framework.dart:2891:6)
#6 BuildOwner.finalizeTree.<anonymous closure> (package:flutter/src/widgets/framework.dart:2950:11)
#7 BuildOwner.finalizeTree (package:flutter/src/widgets/framework.dart:3032:8)
#8 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:885:19)
#9 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:378:5)
#10 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1175:15)
#11 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1104:9)
#12 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1015:5)
#16 _invoke (dart:ui/hooks.dart:150:10)
#17 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:318:5)
#18 _drawFrame (dart:ui/hooks.dart:115:31)
(elided 3 frames from dart:async)
====================================================================================================
在得到这个异常后,当我点击屏幕时,我多次得到相同的异常(7次)
这是我的代码,我使用MVVM架构和riverpod。
import 'package:b2b/export.dart';
class CreateStorePage extends ConsumerStatefulWidget {
const CreateStorePage({
Key? key,
}) : super(key: key);
@override
ConsumerState<ConsumerStatefulWidget> createState() =>
_CreateStorePageState();
}
class _CreateStorePageState
extends BaseConsumerState<CreateStorePage, CreateStoreViewModel> {
GlobalKey<ScaffoldState> createStoreScaffoldKey = GlobalKey<ScaffoldState>();
@override
void initState() {
super.initState();
viewModel().pageController = PageController(initialPage: viewModel().index);
viewModel().storeNameFormKey = GlobalKey<FormState>();
viewModel().discountAmountFormKey = GlobalKey<FormState>();
viewModel().eligibleFormKey = GlobalKey<FormState>();
viewModel().getCategoriesData();
}
@override
Widget customBuild(BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
viewModel().cancelBorderColor();
},
child: Scaffold(
key: createStoreScaffoldKey,
backgroundColor: colors.primaryLight,
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
LinearProgressIndicator(
valueColor: AlwaysStoppedAnimation(colors.accentPrimary),
value: viewModel().progressIndicatorValue,
backgroundColor: colors.accentPrimaryopac,
minHeight: sizes.heightRatio! * 7,
),
Expanded(
child: PageView.builder(
physics: const NeverScrollableScrollPhysics(),
controller: viewModel().pageController,
itemBuilder: (context, index) {
return SizedBox(
height: 500,
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
verticalSpacer(12),
Padding(
padding: EdgeInsets.symmetric(
horizontal: horizontalValue(16),
vertical: verticalValue(16),
),
child:
BoldTitleText(Constants.headingName[index]),
),
verticalSpacer(49),
viewModel().getBlockList()[0]
? Padding(
padding: EdgeInsets.symmetric(
horizontal: horizontalValue(16),
),
child: SizedBox(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
AapayTextView(
showCursor: true,
readOnly: false,
containerColor: colors.lightGrey,
hasTextLengthLimitation: false,
textFieldEnable: true,
isPhoneField: false,
textFieldHintText: Constants
.enterYourBusinessName,
keyboardType: TextInputType.text,
onTap: (value, formKey) {
viewModel().setFormKey(1);
viewModel().texFieldCheck(
value, formKey);
},
hasSuffix:
viewModel().nameFieldSuffix,
formKey:
viewModel().storeNameFormKey,
controller:
viewModel().nameController,
boarderColor:
viewModel().boarderColor,
containerBorderColor: () {
viewModel().setBoarderColor();
},
cancelBorderColor: () {
viewModel().cancelBorderColor();
},
onTextFieldTap: () {},
showValidation: () {
viewModel()
.showValidationError();
},
cancelValidation: () {
viewModel()
.cancelValidationError();
},
allowOtherCharacters: false,
),
Visibility(
visible:
viewModel().showValidation,
child: ValidationError(
textMessage: viewModel()
.storeBusinessNameTextViewStateAuthorized
? ''
: Constants
.enterYourValidBusinessName,
),
),
],
),
),
)
: const SizedBox.shrink(),
verticalSpacer(10),
//Shopping Discount Block
viewModel().getBlockList()[1]
? ScreenTab(
selected:
viewModel().getDiscountChipList(),
isSelected: viewModel().discount1,
containerBorderColor: () {},
cancelBorderColor: () {},
formKey:
viewModel().discountAmountFormKey,
text: Constants
.howMuchDiscountWillYouGiveOnTheShopping,
onChipTap: (int value, String text) {
viewModel()
.setDiscountTextfieldInitialVal(
text);
viewModel().isDiscountChipPressed();
},
textFieldInitialVal:
viewModel().discountTextFieldVal,
tabController:
viewModel().discountAMountController,
onTextFieldChange: (String value,
GlobalKey<FormState> formKey) {
viewModel().setFormKey(2);
viewModel()
.texFieldCheck(value, formKey);
},
isError: viewModel()
.discountTextViewStateAuthorized,
hasSuffix:
viewModel().discountFieldSuffix,
boarderColor: false,
)
: const SizedBox.shrink(),
verticalSpacer(20),
//Eligible Discount Block
viewModel().getBlockList()[2]
? ScreenTab(
selected:
viewModel().getEligibleForDiscount(),
isSelected: viewModel().discount2,
containerBorderColor: () {},
cancelBorderColor: () {},
boarderColor: false,
formKey: viewModel().eligibleFormKey,
text: Constants
.afterHowMuchPurchaseCustomersWillBeEligible,
onChipTap: (int value, String text) {
viewModel()
.setEligibleTextfieldInitialVal(
text);
viewModel().isEligibleChipPressed();
},
textFieldInitialVal:
viewModel().eligibleTextFieldVal,
tabController: viewModel()
.eligibleCriteriaController,
onTextFieldChange: (String value,
GlobalKey<FormState> formKey) {
viewModel().setFormKey(3);
viewModel()
.texFieldCheck(value, formKey);
},
isError: viewModel()
.eligibilityTextViewStateAuthorized,
hasSuffix:
viewModel().eligibilityFieldSuffix,
)
: const SizedBox.shrink(),
verticalSpacer(20),
//Categories Block
viewModel().getBlockList()[3]
? CategoriesBlock(
blockList: viewModel().getBlockList(),
buttonState: (value) =>
viewModel().buttonState(value),
getList: viewModel().getList(),
)
: const SizedBox.shrink(),
verticalSpacer(30),
//Store Image Block
viewModel().getBlockList()[6]
? StoreImage(
image: viewModel().image,
getImage: (value) {
viewModel().getImage(value);
},
blockList: viewModel().getBlockList(),
)
: const SizedBox.shrink(),
verticalSpacer(30),
//Branches Block
viewModel().getBlockList()[7]
? const StoreBranches()
: const SizedBox.shrink(),
verticalSpacer(30),
//Branches List
viewModel().getBlockList()[7]
? BranchesList(
itemCount:
viewModel().getBranchList().length,
getLocationNameList:
viewModel().getLocationNameList(),
getBranchesData:
viewModel().getBranchList(),
)
// Container(
// padding: EdgeInsets.symmetric(
// horizontal: horizontalValue(20),
// ),
// height: (sizes.heightRatio! * 35) *
// viewModel().getBranchList().length,
// child: IntrinsicHeight(
// child: ListView.separated(
// shrinkWrap: true,
// itemCount: viewModel()
// .getBranchList()
// .length,
// itemBuilder:
// (BuildContext context, index) {
// return TextWidget(
// text:
// '${viewModel().getLocationNameList()[index]} ( ${viewModel().getBranchList()[index].name})',
// textSize: 17,
// fontFamilyType:
// FontFamily.manropeMedium,
// textColor: colors.primaryDark,
// );
// },
// separatorBuilder: (_, index) {
// return verticalSpacer(10);
// },
// ),
// ),
// )
: const SizedBox.shrink(),
],
),
),
);
},
onPageChanged: (index) {
viewModel().index == 7 ? viewModel().index : index;
print(viewModel().index);
viewModel().setBlockState(
index,
);
viewModel().index = viewModel().index + 1;
viewModel().refreshState();
},
itemCount: viewModel().getBlockList().length,
),
)
],
),
),
resizeToAvoidBottomInset: true,
bottomNavigationBar: Padding(
padding: EdgeInsets.symmetric(
horizontal: horizontalValue(20),
vertical: verticalValue(20),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
FilledButton(
color: viewModel().filledButtonState
? colors.accentPrimary
: CustomizedTheme.blackOpac01,
textColor: colors.primaryLight,
showLockIcon: false,
isLoading: false,
text: Constants.branchAddedVal
? Constants.done
: Constants.next,
onTap: viewModel().filledButtonState
? () {
if (viewModel().index == 8 &&
Constants.branchAddedVal == false) {
GoRouter.of(createStoreScaffoldKey
.currentState!.context)
.push(mapAddLocationPageRoute);
FocusScope.of(createStoreScaffoldKey
.currentState!.context)
.unfocus();
} else if (viewModel().index == 8 &&
Constants.branchAddedVal == true) {
viewModel().navigateToHomePage();
FocusScope.of(createStoreScaffoldKey
.currentState!.context)
.unfocus();
} else {
viewModel().pageController.nextPage(
duration: const Duration(milliseconds: 1),
curve: Curves.linear);
FocusScope.of(createStoreScaffoldKey
.currentState!.context)
.unfocus();
}
}
: null,
),
viewModel().getBlockList()[7]
? verticalSpacer(24)
: const SizedBox.shrink(),
viewModel().getBlockList()[7] && !Constants.branchAddedVal
? FilledButton(
text: Constants.finishAndAddLater,
onTap: viewModel().filledButtonState
? () {
GoRouter.of(createStoreScaffoldKey
.currentState!.context)
.go(homePageRoute);
FocusScope.of(createStoreScaffoldKey
.currentState!.context)
.unfocus();
}
: null,
color: viewModel().filledButtonState
? colors.accentPrimary
: CustomizedTheme.blackOpac01,
textColor: colors.primaryLight,
showLockIcon: false,
isLoading: false,
)
: const SizedBox.shrink(),
],
),
),
),
),
);
}
@override
StateNotifierProvider<BaseViewModel, BaseState> getProvider() =>
createStoreViewModel;
@override
void initializeListener(
StateNotifierProvider<BaseViewModel, BaseState> provider) {
ref.listen(
provider,
(previous, next) {
switch (next.runtimeType) {
case RefreshCreateStorePage:
{
setState(() {});
break;
}
case NavigateToHomePageState:
{
GoRouter.of(createStoreScaffoldKey.currentState!.context)
.go(homePageRoute);
break;
}
}
},
);
}
}
1条答案
按热度按时间h9vpoimq1#
对于不同的小部件多次使用相同的GlobalKey,最好使用基于索引或uuid的单独键