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 restart
die App. Und ich weiß, dass das nicht die beste Lösung ist.
Keine Kommentare:
Kommentar veröffentlichen