Я пытаюсь заставить настраиваемый виджет с отслеживанием состояния работать во флаттере. Он называется LetterTextForm и содержит некоторые настройки макета и TextField.
Я хочу, чтобы было легко получить текст, введенный в TextField виджета, с помощью какого-то метода получения в теле виджета, который возвращает TextEditingController.text. Проблема в том, что когда я делаю контроллер TextEditingController последней переменной следующим образом:
class LetterTextForm extends StatefulWidget {
LetterTextForm({@required this.label, this.prefixIcon});
final Widget prefixIcon;
final String label;
final TextEditingController controller = TextEditingController();
String get textEntered => controller.text;
@override
_LetterTextFormState createState() => _LetterTextFormState();
}
class _LetterTextFormState extends State<LetterTextForm> {
@override
void initState() {
super.initState();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return TextField(
controller: widget.controller,
decoration: InputDecoration(
prefixIcon: widget.prefixIcon,
labelText: widget.label,
)
);
}
}
возникает следующая ошибка: TextEditingController использовался после удаления.
Я подумал, что, возможно, проблема в том, что контроллер не должен быть окончательным, поэтому я переместил контроллер в класс состояния и сделал функцию в классе состояния textCallback, которая изменяет неокончательную строку, которая находится в классе виджета. Этот способ работает, но нарушает неизменяемость виджета:
class LetterTextForm extends StatefulWidget {
LetterTextForm({@required this.label, this.prefixIcon});
final Widget prefixIcon;
final String label;
String text = '';
String get textEntered => text;
@override
_LetterTextFormState createState() => _LetterTextFormState();
}
class _LetterTextFormState extends State<LetterTextForm> {
var controller = TextEditingController();
void textCallback() {
widget.text = controller.text;
}
@override
void initState() {
super.initState();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return TextField(
controller: controller,
decoration: InputDecoration(
prefixIcon: widget.prefixIcon,
labelText: widget.label,
)
);
}
}
Есть ли способ сделать это, что и 1) не нарушает неизменяемость, и 2) не удаляет TextEditingController () сразу же, когда пользователь нажимает Enter?
Он работает, когда я избавляюсь от метода dispose (), но похоже, что позже это может вызвать некоторые проблемы с производительностью / эффективностью памяти. Может, я не понимаю, о чем там говорю ...
Возможно, мне стоит попробовать что-то совершенно другое и разместить TextEditingControllers дальше в дереве с предками виджета LetterTextForm, а не внутри виджета?