我遇到了错误:texteditingcontroller 在被释放后被使用。一旦您在 TextEditingController 上调用 dispose(),它就不能再使用了。
我第一次浏览该页面时没有遇到此错误,但当我返回并尝试第二次转到同一屏幕时遇到了此错误。
这是我的 2 屏代码,包括命名的循环代码。最后我还将包含完整代码的 git 链接。
登录屏幕
import 'package:batch8_taskmanager_project/ui/screens/sign_up_screen.dart';
import 'package:batch8_taskmanager_project/ui/widgets/screen_background.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
class SignInScreen extends StatefulWidget {
const SignInScreen({super.key});
static const String name = '/sign-in-screen';
@override
State<SignInScreen> createState() => _SignInScreenState();
}
GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final TextEditingController _emailTEController = TextEditingController();
final TextEditingController _passwordTEController = TextEditingController();
class _SignInScreenState extends State<SignInScreen> {
@override
Widget build(BuildContext context) {
final textStyle = Theme.of(context).textTheme;
return Scaffold(
resizeToAvoidBottomInset: false,
body: ScreenBackground(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(
height: 68,
),
Text(
"Get Started With",
style: textStyle.titleLarge,
),
const SizedBox(
height: 24,
),
TextFormField(
controller: _emailTEController,
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(hintText: "Email Address"),
),
const SizedBox(
height: 24,
),
TextFormField(
controller: _passwordTEController,
obscureText: true,
decoration: const InputDecoration(hintText: "Password"),
),
const SizedBox(
height: 24,
),
ElevatedButton(onPressed: () {}, child: const Icon(Icons.double_arrow)),
const SizedBox(
height: 48,
),
TextButton(onPressed: () {}, child: const Text("Forgot Password?")),
const SizedBox(
height: 24,
),
_buildSignIn()
],
),
),
)),
);
}
Widget _buildSignIn() {
return RichText(
text: TextSpan(
text: "Don't have an account? ",
style: const TextStyle(color: Colors.grey),
children: [
TextSpan(
text: "Sign up",
style: const TextStyle(
color: Colors.green, fontWeight: FontWeight.bold),
recognizer: TapGestureRecognizer()..onTap = () {
Navigator.pushNamed(context, SignupScreen.name);
})
]),
);
}
@override
void dispose() {
_emailTEController.dispose();
_passwordTEController.dispose();
super.dispose();
}
}
注册屏幕
import 'package:batch8_taskmanager_project/ui/widgets/screen_background.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
class SignupScreen extends StatefulWidget {
const SignupScreen({super.key});
static const String name = '/sign-up-screen';
@override
State<SignupScreen> createState() => _SignupScreenState();
}
GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final TextEditingController _emailTEController = TextEditingController();
final TextEditingController _firstNameTEController = TextEditingController();
final TextEditingController _lastNameTEController = TextEditingController();
final TextEditingController _mobileTEController = TextEditingController();
final TextEditingController _passwordTEController = TextEditingController();
class _SignupScreenState extends State<SignupScreen> {
@override
Widget build(BuildContext context) {
final textStyle = Theme.of(context).textTheme;
return Scaffold(
resizeToAvoidBottomInset: false,
body: ScreenBackground(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(
height: 68,
),
Text(
"Join with Us",
style: textStyle.titleLarge,
),
const SizedBox(
height: 24,
),
TextFormField(
controller: _emailTEController,
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(hintText: "Email Address"),
),
const SizedBox(
height: 12,
),
TextFormField(
controller: _firstNameTEController,
decoration: const InputDecoration(hintText: "First Name"),
),
const SizedBox(
height: 12,
),
TextFormField(
controller: _lastNameTEController,
decoration: const InputDecoration(hintText: "Last Name"),
),
const SizedBox(
height: 12,
),
TextFormField(
controller: _mobileTEController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: "Mobile"),
),
const SizedBox(
height: 12,
),
TextFormField(
controller: _passwordTEController,
obscureText: true,
decoration: const InputDecoration(hintText: "Password"),
),
const SizedBox(
height: 24,
),
ElevatedButton(onPressed: () {}, child: const Icon(Icons.double_arrow)),
const SizedBox(
height: 48,
),
_buildSignUp()
],
),
),
)),
);
}
Widget _buildSignUp() {
return RichText(
text: TextSpan(
text: "Have an account? ",
style: const TextStyle(color: Colors.grey),
children: [
TextSpan(
text: "Sign in",
style: const TextStyle(
color: Colors.green, fontWeight: FontWeight.bold),
recognizer: TapGestureRecognizer()..onTap = () {
Navigator.pop(context);
})
]),
);
}
@override
void dispose() {
_emailTEController.dispose();
_firstNameTEController.dispose();
_lastNameTEController.dispose();
_mobileTEController.dispose();
_passwordTEController.dispose();
super.dispose();
}
}
命名路由代码
initialRoute: '/',
onGenerateRoute: (RouteSettings settings){
late Widget widget;
if(settings.name == SplashScreen.name){
widget = const SplashScreen();
}else if(settings.name == SignInScreen.name){
widget = const SignInScreen();
}else if(settings.name == SignupScreen.name){
widget = const SignupScreen();
}
return MaterialPageRoute(builder: (_) => widget);
},
https://github.com/jahangirsim/batch8_taskmanager_project.git
发生错误是因为您正在方法
TextEditingController
内部处理dispose
,但控制器已全局初始化。因此,第一次进入页面不会抛出错误,但后续几次都会抛出错误。要修复此错误,您必须将初始化移到 StatefulWidget 内部。经过此更改后,每次创建 Widget 时,
TextEditingController
都会在 Widget 生命周期内初始化并处置GlobalKey
。如果仅在 Widget 内使用,您还应该将 放在 Widget 内。