为什么点击flutter中的Done后文本从文本字段中消失?

ulydmbyx  于 2022-12-19  发布在  Flutter
关注(0)|答案(2)|浏览(218)

我有一个文本字段,用户可以在其中输入文本。但当我输入文本并按下“完成”按钮时,遇到了一个问题-文本从文本字段中消失,就像它从未存在过一样。但当字段处于活动状态并输入字符时,所有内容都是可见的。为什么单击“完成”按钮后文本从文本字段中消失?

class CommentWidget extends StatelessWidget {
  final Function(String) onChanged;
  final String? textForm;
  final bool isHelpPage;

  CommentWidget({Key? key, required this.onChanged, required this.textForm, required this.isHelpPage})
      : super(key: key);

  final TextEditingController controller = TextEditingController();
  String value = '';

  @override
  Widget build(BuildContext context) {
    final Size size = MediaQuery.of(context).size;
    controller.text = textForm ?? '';

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        isHelpPage
        ? const SizedBox()
        : const ResizedText(
          'Comments',
          textStyle: constants.Styles.smallTextStyleWhite,
        ),
        SizedBox(
          height: UiSize.getHeight(15, size),
        ),
        Container(
          height: UiSize.getHeight(isHelpPage ? 290 : 150, size),
          width: UiSize.getWidth(360, size),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(8),
            border: Border.all(
              color: constants.Colors.purpleMain,
              width: 0.5,
            ),
          ),
          child: Padding(
            padding: EdgeInsets.only(
              top: UiSize.getHeight(16, size),
              left: UiSize.getWidth(18, size),
              right: UiSize.getWidth(18, size),
              bottom: UiSize.getHeight(16, size),
            ),
            child: TextField(
              maxLines: isHelpPage ? 10 :4,
              maxLength: isHelpPage ? 1500 : 450,
              controller: controller,
              style: constants.Styles.smallerBookTextStyleWhiteOpacity,
              textInputAction: TextInputAction.done,
              onChanged: (text) {
                onChanged(text);
                value = text;
              },
              decoration: InputDecoration(
                border: InputBorder.none,
                helperStyle: constants.Styles.smallerBookTextStyleWhiteOpacity,
                hintStyle: constants.Styles.smallerBookTextStyleWhiteOpacity,
                hintText: 'Here you can describe the problem in more detail',
              ),
            ),
          ),
        ),
      ],
    );
  }
}
1bqhqjot

1bqhqjot1#

我的猜测是,您可能通过调用setState(...)在父小部件中重建文本字段。
controller.text = textForm ?? '';然后擦除文本,因为每次构建小部件时都要重置文本。
解决方案:使小部件成为StatefulWidget,并让它缓存TextField的值。
这可能看起来像这样

class TextfieldWithCache extends StatefulWidget {
  const TextfieldWithCache(this.initialValue, this.onUpdate);
  
  final String initialValue;
  final Function(String) onUpdate;

  @override
  State<TextfieldWithCache> createState() => TextfieldWithCacheState();
}

class TextfieldWithCacheState extends State<TextfieldWithCache> {
  
  // if not used in this widget, the value can be deleted as well
  String _cachedValue;
  
  Widget build(BuildContext context) {
    return TextFormField(
      initialValue: widget.initialValue,
      onChanged: (String value) {
        widget.onUpdate(value);
        _cachedValue = value;
      },
    );
  }
}

注意:如果您不使用TextfieldWithCache中的缓存值,则也可以将其移除。
其核心在于使用StatefulWidget并摆脱小部件创建中涉及的所有helper方法。

1tuwyuhd

1tuwyuhd2#

尝试将ReportBody更改为Statefull Widget,并将文本编辑控制器声明为,然后在initState()中初始化它。

late final TextEditingController controller;

@override
  void initState() {
    controller = TextEditingController();
    super.initState();
  }

然后将此控制器作为命名参数传递给CommentWidget,并将此控制器用于TextFormField。
希望能成功。

相关问题