I have a screen to create a post. There is a TextFormField
there and I added dispose
to its TextEditingController
. However, I get an error:
════════ Exception caught by widgets library ═══════════════════════════════════
A TextEditingController was used after being disposed.
════════════════════════════════════════════════════════════════════════════════
If my understanding is correct, I think it's saying that I can't use the disposed TextEditingController
when I'm pushed to another screen and popped. Hope you guys can tell me if my understanding is correct.
I referred this answer but it didn't solve my problem.
My code:
TextEditingController messageController = TextEditingController();
class CreatePostScreen extends ConsumerStatefulWidget {
const CreatePostScreen({super.key});
@override
ConsumerState<CreatePostScreen> createState() => _CreatePostScreenState();
}
class _CreatePostScreenState extends ConsumerState<CreatePostScreen> with AutomaticKeepAliveClientMixin {
@override
void dispose() {
messageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
super.build(context);
…
return Scaffold(
appBar: AppBar(
…
title: Text("Create post"),
),
body: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
children: [
…
TextFormField(
controller: enquiryMessageController,
style: const TextStyle(color: Colors.black),
decoration: InputDecoration(
border: InputBorder.none,
hintText: "What do you wish to enquire?",
hintStyle: const TextStyle(color: Colors.black),
),
keyboardType: TextInputType.text,
textInputAction: TextInputAction.done,
),
],
),
),
);
}
}
messageController
is outside ConsumerStatefulWidget
, because the code is to make the text in TextFormField
not disappear, please refer to this answer.
Feel free to leave a comment if you need more information.
I can't use a disposed TextEditingController
when pushed to another screen and popped, is my understanding correct? I would appreciate any help. Thank you in advance!
CodePudding user response:
You can try defining the controller this way:
class CreatePostScreen extends ConsumerStatefulWidget {
const CreatePostScreen({super.key});
@override
ConsumerState<CreatePostScreen> createState() => _CreatePostScreenState();
}
class _CreatePostScreenState extends ConsumerState<CreatePostScreen> with AutomaticKeepAliveClientMixin {
late TextEditingController messageController;
@override
void initState() {
messageController = TextEditingController();
super.initState();
}
@override
void dispose() {
messageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
super.build(context);
…
return Scaffold(
appBar: AppBar(
…
title: Text("Create post"),
),
body: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
children: [
…
TextFormField(
controller: enquiryMessageController,
style: const TextStyle(color: Colors.black),
decoration: InputDecoration(
border: InputBorder.none,
hintText: "What do you wish to enquire?",
hintStyle: const TextStyle(color: Colors.black),
),
keyboardType: TextInputType.text,
textInputAction: TextInputAction.done,
),
],
),
),
);
}
}
CodePudding user response:
As I see you are declaring it as a global variable. When the screen is popped (removed from widget tree), dispose is executed. So your global TextEditingController is disposed. It is a very bad practice. You need to define it inside _CreatePostScreenState class. So whenever the screen widget initiated, a new controller widget will also be created. I hope, this solves your problem. If not, then please edit the question, add error messages, and code lines which you find from error log.