【问题标题】:setState doesn't rerender textformfieldsetState 不会重新呈现文本表单字段
【发布时间】:2022-01-18 12:02:02
【问题描述】:

我正在尝试将 PasswordField 创建为具有后缀的 TextFormField,它应该允许切换输入字符串的可见性。我收到的问题是,我可以在真假之间切换 obscureText,但不会发生重新渲染。我希望有人可以帮助我解决这个问题。我将在下面添加代码

class _WFPasswordInputState extends State<WFPasswordInput> {
  TextEditingController? controller;
  TextFormField? formField;
  late bool obscureText;
  late FocusNode _focusNode;
  final AppTheme style = AppTheme();

  @override
  void initState() {
    _focusNode = FocusNode();
    obscureText = widget.obscureText;
    super.initState();
  }

  @override
  void dispose() {
    _focusNode.dispose();
    formField!.controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    String formatted = widget.value.value?.toString() ?? '';
    if (formField == null) {
      TextEditingController controller;
      if (widget.controller == null) {
        controller = TextEditingController(text: formatted);
      } else {
        controller = widget.controller!;
      }
      formField = createTextFormField();
    } else {
      Future.delayed(
        Duration.zero,
        () {
          if (formField!.controller?.text !=
              (widget.value.display == null
                  ? null
                  : widget.value.value.toString())) {
            String formatted = widget.value.value!;
            if (formField!.controller!.text.isEmpty) {
              formatted = "";
            }
            formField!.controller?.text = formatted;
            formField!.controller?.selection = TextSelection(
              baseOffset: formatted.length,
              extentOffset: formatted.length,
            );
          }
        },
      );
    }
    return formField!;
  }

  TextFormField createTextFormField() {
    return TextFormField(
      enabled: widget.enabled,
      controller: controller,
      keyboardType: widget.inputType,
      focusNode: widget.focusNode,
      obscureText: obscureText,
      textAlign: widget.textAlignment,
      inputFormatters: widget.inputFormatters,
      maxLines:
          widget.inputType == TextInputType.multiline ? widget.maxLines : 1,
      minLines: widget.minLines,
      style: widget.textStyle ??
          style.textStyles.bodyText1!
              .copyWith(color: Colors.white.withOpacity(0.5)),
      decoration: CustomInputDecoration(
          hintStyle: AppTheme()
              .textStyles
              .bodyText1!
              .copyWith(color: Colors.white.withOpacity(0.5)),
          hintText: widget.hintText,
          suffix: passwordIcons(),
          contentPadding: style.px4y2),
      onChanged: (value) {
        widget.value.value = value;
      },
      validator: widget.validator,
    );
  }

  Widget passwordIcons() {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        IconButton(
          onPressed: () {
            setState(() {
              obscureText = !obscureText;
              print(obscureText);
            });
          },
          icon: Icon(
            obscureText ? Icons.visibility : Icons.visibility_off,
            color: style.white.withOpacity(0.5),
          ),
          color: style.white,
        ),
        IconButton(
          onPressed: showPasswordAlert,
          icon: const Icon(Icons.info_outline),
          color: style.white,
        ),
      ],
    );
  }
}

所以这基本上应该如何工作是我打电话给 obscureText = widget.obscureText; 在 initState 方法中。并且每次我单击 passwordIcons Widget setState 中的 IconButton 时,都应该调用它并根据 obscureText 值重新渲染它。但我只是没有看到错误。

提前谢谢你。

【问题讨论】:

    标签: flutter textformfield


    【解决方案1】:

    您的方法的问题是您只使用此代码创建了一次formField

    if (formField == null) {
      ...
      formField = createTextFormField();
    } 
    

    您是在强制框架不要重建此小部件,但使用 setState 的全部意义在于重建。

    这样 Flutter 框架在调用 setState 时不会更新这个小部件。相反,将此小部件直接添加到您的小部件树中,setState 将起作用。而不是这个:

    return formField!;
    

    试试这个:

    return TextFormField(
      enabled: widget.enabled,
      controller: controller,
      keyboardType: widget.inputType,
      focusNode: widget.focusNode,
      obscureText: obscureText,
      ...
    

    【讨论】:

    • 太棒了!!!非常感谢!
    • 不客气。通常建议使用自定义小部件的类而不是函数。
    • 感谢您的提示。对性能有影响吗?
    • 您的意思是自定义小部件而不是功能,还是我的答案中的解决方案?
    • 无论如何,我建议阅读this以更好地理解。
    猜你喜欢
    • 2017-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    • 2020-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多