GOOGLE ADS

Sonntag, 17. April 2022

Beim Fertigstellen des Widget-Baums wurde die folgende Assertion ausgelöst: Mehrere Widgets verwendeten denselben GlobalKey-Flatter

Ich habe ein Formular mit zwei TextFormFields und ich versuche, die TextFormFields zu validieren, aber ich bekomme den folgenden Fehler


The following assertion was thrown while finalizing the widget tree:
Multiple widgets used the same GlobalKey.
The key [LabeledGlobalKey<FormState>#fb338] was used by multiple widgets. The parents of those widgets were:
- _SingleChildViewport(renderObject: _RenderSingleChildViewport#51664)
- _SingleChildViewport(renderObject: _RenderSingleChildViewport#d9e77)
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:2868:13)
#1 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:539:8)
#2 BuildOwner._debugVerifyGlobalKeyReservation.<anonymous closure>.<anonymous closure> (package:flutter/src/widgets/framework.dart:2815:20)
#3 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:539:8)
#4 BuildOwner._debugVerifyGlobalKeyReservation.<anonymous closure> (package:flutter/src/widgets/framework.dart:2811:36)
#5 BuildOwner._debugVerifyGlobalKeyReservation (package:flutter/src/widgets/framework.dart:2876:6)
#6 BuildOwner.finalizeTree.<anonymous closure> (package:flutter/src/widgets/framework.dart:2935:11)
#7 BuildOwner.finalizeTree (package:flutter/src/widgets/framework.dart:3016:8)
#8 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:884:19)
#9 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:363:5)
#10 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1144:15)
#11 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1081:9)
#12 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:995:5)
#16 _invoke (dart:ui/hooks.dart:151:10)
#17 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:308:5)
#18 _drawFrame (dart:ui/hooks.dart:115:31)
(elided 3 frames from dart:async)
====================================================================================================

Unten ist, wie mein Code aussieht


import 'dart:math';
import 'package:blur/blur.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fullscreen/fullscreen.dart';
import 'package:logger/logger.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:video_player/video_player.dart';
class Login extends StatefulWidget {
const Login({Key? key}): super(key: key);
@override
State<Login> createState() => _LoginState();
}
class _LoginState extends State<Login> {
final loginFormKey = GlobalKey<FormState>();
TextEditingController phoneNoController = TextEditingController();
TextEditingController pinController = TextEditingController();
FocusNode phoneNoFocusNode = FocusNode();
FocusNode pinFocusNode = FocusNode();
int phoneMaxInputLength = 13;
int pinMaxInputLength = 4;
bool phoneNoHasFocus = false;
bool pinNoHasFocus = false;
bool showPhoneNoErrorSuffixIcon = false;
bool showPinErrorSuffixIcon = false;
bool enablePhoneNoAutoValidation = false;
bool enablePinAutoValidation = false;
bool obscurePin = true;
late VideoPlayerController videoPlayerController;
@override
void initState() {
super.initState();
videoPlayerController = VideoPlayerController.asset("videos/intro.mp4")
..initialize().then((_) {
videoPlayerController.setVolume(0.2);
videoPlayerController.setPlaybackSpeed(1);
videoPlayerController.setLooping(true);
videoPlayerController.play();
setState(() {});
});
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
clearPrefs();
}
@override
void dispose() {
super.dispose();
videoPlayerController.dispose();
phoneNoController.dispose();
phoneNoFocusNode.dispose();
pinController.dispose();
pinFocusNode.dispose();
}
void clearPrefs() async {
final prefs = await SharedPreferences.getInstance();
await prefs.clear();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: videoPlayerController.value.isInitialized
? Stack(alignment: Alignment.center, children: [
SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: VideoPlayer(videoPlayerController),
),
Container(
width: double.infinity,
height: 400,
margin: const EdgeInsets.only(left: 20, right: 20),
child: SingleChildScrollView(
child: Form(
key: loginFormKey,
child: Column(
children: [
Container(
padding: const EdgeInsets.only(top: 5, bottom: 5),
margin: const EdgeInsets.only(top: 10, bottom: 5),
child: Text(
"Sign In",
textAlign: TextAlign.center,
style: Config.boldTitleTextStyle,
)),
Container(
width: double.infinity,
padding: const EdgeInsets.only(
top: 5, bottom: 5, left: 5, right: 5),
margin: const EdgeInsets.only(
top: 5, bottom: 5, right: 5, left: 5),
child: TextFormField(
onChanged: (phoneNo) {
setState(() {
enablePhoneNoAutoValidation = true;
});
},
autovalidateMode: enablePhoneNoAutoValidation
? AutovalidateMode.onUserInteraction
: AutovalidateMode.disabled,
maxLength: phoneMaxInputLength,
focusNode: phoneNoFocusNode,
controller: phoneNoController,
cursorHeight: 20,
decoration: InputDecoration(
labelText: "Enter Phone Number",
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(10)),
suffixIcon: showPhoneNoErrorSuffixIcon
? Tooltip(
message:
"We require a phone number to be able to proceed",
triggerMode: TooltipTriggerMode.tap,
child: const Icon(
Icons.error_outline_rounded,
color: Colors.red),
decoration: BoxDecoration(
color: Colors.black,
borderRadius:
BorderRadius.circular(20.0),
))
: null),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],
validator: (phoneNo) {
if (phoneNo!.isEmpty) {
phoneNoFocusNode.requestFocus();
phoneNoHasFocus = true;
WidgetsBinding.instance!
.addPostFrameCallback((_) {
setState(() {
showPhoneNoErrorSuffixIcon = true;
});
});
return "Please Enter Phone Number";
} else {
phoneNoHasFocus = false;
WidgetsBinding.instance!
.addPostFrameCallback((_) {
setState(() {
showPhoneNoErrorSuffixIcon = false;
});
});
return null;
}
},
)),
Container(
width: double.infinity,
padding: const EdgeInsets.only(
top: 5, bottom: 5, left: 5, right: 5),
margin: const EdgeInsets.only(
top: 5, bottom: 5, right: 5, left: 5),
child: TextFormField(
obscureText: obscurePin,
onChanged: (pin) {
setState(() {
enablePinAutoValidation = true;
});
},
autovalidateMode: enablePinAutoValidation
? AutovalidateMode.onUserInteraction
: AutovalidateMode.disabled,
maxLength: pinMaxInputLength,
focusNode: pinFocusNode,
controller: pinController,
cursorHeight: 20,
decoration: InputDecoration(
labelText: "Enter Pin",
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(10)),
suffixIcon: showPinErrorSuffixIcon
? Tooltip(
message:
"We require a pin to be able to proceed",
triggerMode: TooltipTriggerMode.tap,
child: const Icon(
Icons.error_outline_rounded,
color: Colors.red),
decoration: BoxDecoration(
color: Colors.black,
borderRadius:
BorderRadius.circular(20.0),
))
: IconButton(
icon: Icon(
obscurePin
? Icons.visibility
: Icons.visibility_off,
),
onPressed: () {
setState(() {
obscurePin =!obscurePin;
});
},
)),
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly
],
validator: (pin) {
if (pin!.isEmpty) {
if (!phoneNoHasFocus){
pinFocusNode.requestFocus();
}
pinNoHasFocus = true;
WidgetsBinding.instance!
.addPostFrameCallback((_) {
setState(() {
showPinErrorSuffixIcon = true;
});
});
return "Please Enter Phone Number";
} else {
pinNoHasFocus = false;
WidgetsBinding.instance!
.addPostFrameCallback((_) {
setState(() {
showPinErrorSuffixIcon = false;
});
});
return null;
}
},
)),
Container(
width: double.infinity,
padding: const EdgeInsets.only(
top: 5, bottom: 10, left: 5, right: 5),
margin: const EdgeInsets.only(
top: 5, bottom: 10, right: 5, left: 5),
child: ElevatedButton(
onPressed: () {
if (loginFormKey.currentState!.validate()) {
Logger().i("FieldsAreEmpty${false}");
} else {
Logger().i("FieldsAreEmpty${true}");
}
},
child: Text("Proceed".toUpperCase()),
style: ElevatedButton.styleFrom(
shape: const StadiumBorder(),
))),
],
)),
),
).frosted(
blur: 10,
borderRadius: BorderRadius.circular(20),
padding: const EdgeInsets.all(1),
)
])
: Container(),
));
}
}

Ich habe versucht, ein GlobalKey<FormState>()für jedes TextFormField zu erstellen und dem Schlüssel jedes TextFormField zuzuweisen, aber es bringt immer noch den Fehler. Ich habe auch versucht, das Formular außerhalb des Containers zu platzieren, aber es bringt immer noch den Fehler


Lösung des Problems

Habe den gleichen Fehler in Flutter 2.10. Ich hot restartdie App. Und ich weiß, dass das nicht die beste Lösung ist.

Keine Kommentare:

Kommentar veröffentlichen

Warum werden SCHED_FIFO-Threads derselben physischen CPU zugewiesen, obwohl CPUs im Leerlauf verfügbar sind?

Lösung des Problems Wenn ich das richtig verstehe, versuchen Sie, SCHED_FIFO mit aktiviertem Hyperthreading ("HT") zu verwenden, ...