【问题标题】:Flutter - Textfield lose focus when text is visibleFlutter - 文本可见时文本字段失去焦点
【发布时间】:2020-05-06 21:15:23
【问题描述】:

在我的项目中,我为密码创建了一个文本字段,并创建了一个显示和隐藏密码的方法。发生的情况是,当我按下图标显示文本时,键盘和光标消失了,我的意思是,焦点丢失了。

当我按下图标时它不会失去焦点,我该如何做到这一点?谢谢

class ExampleLoginFocus extends StatefulWidget {
  @override
  _ExampleLoginFocusState createState() => _ExampleLoginFocusState();
}

class _ExampleLoginFocusState extends State<ExampleLoginFocus> {
  FocusNode focusPass;

  var pass = '';
  bool passwordVisible;

  @override
  void initState() {
    super.initState();
    passwordVisible = true;
    focusPass = FocusNode();
  }

  Widget password() {
    return TextField(
      obscureText: passwordVisible,
      focusNode: focusPass,
      decoration: InputDecoration(
        suffixIcon: Padding(
          padding: EdgeInsets.only(top: 20, bottom: 0),
            child: IconButton(
          icon: Icon(
            passwordVisible ? Icons.visibility_off : Icons.visibility,
            color: Theme.of(context).primaryColorDark,
          ),
          onPressed: () {
            setState(() {
              passwordVisible = !passwordVisible;
            });
          },
        )),
      ),
      onChanged: (String tex) {
        pass = tex;
        print(pass);
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: password(),
      ),
    );
  }
}

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    我无法测试您的代码,但我有一个自定义文本字段小部件,它允许使用属性来定义是普通文本字段还是密码文本字段,也许这对您有帮助

    class DnetTextField extends StatefulWidget {
      final String label;
      final bool isPasswordField;
      final TextEditingController controller;
      final TextInputType textInputType;
      final TextInputAction textInputAction;
      final FormFieldValidator validator;
      final IconData icon;
      final Color color;
      final Color errorColor;
      final BuildContext context;
      final FocusNode currentFocus;
      final FocusNode nextFocus;
      final bool autoValidate;
      final double width;
      final ValueChanged<String> onFieldSubmitted;
      final List<TextInputFormatter> inputFormatters;
      final TextCapitalization textCapitalization;
      final int maxLength;
      final bool focusable;
      final String hint;
    
      DnetTextField({
        @required this.context,
        @required this.label,
        @required this.controller,
        this.icon,
        this.color,
        this.errorColor,
        this.textInputType = TextInputType.text,
        this.textInputAction = TextInputAction.done,
        this.validator,
        this.isPasswordField = false,
        this.currentFocus,
        this.nextFocus,
        this.onFieldSubmitted,
        this.autoValidate = false,
        this.width = 266,
        this.inputFormatters,
        this.textCapitalization = TextCapitalization.none,
        this.maxLength = -1,
        this.focusable = true,
        this.hint,
      });
    
      @override
      DnetTextFieldState createState() {
        return DnetTextFieldState();
      }
    }
    
    class DnetTextFieldState extends State<DnetTextField> {
      bool hasErrors = false;
      bool passwordVisible = false;
    
      Color get currentColor => hasErrors ? widget.errorColor : widget.color;
    
      IconData get currentIcon {
        if (widget.isPasswordField) if (passwordVisible)
          return Icons.visibility_off;
        else
          return Icons.visibility;
        else
          return widget.icon;
      }
    
      @override
      void initState() {
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        final border = OutlineInputBorder(
          borderRadius: BorderRadius.all(Radius.circular(10.0)),
          borderSide: BorderSide(color: currentColor),
        );
    
        final focusableTheme = widget.focusable
            ? Theme.of(context)
            : Theme.of(
                context,
              ).copyWith(
                splashFactory: const NoSplashFactory(),
              );
    
        return Container(
          width: widget.width,
          height: 80,
          child: Theme(
            data: focusableTheme,
            child: TextFormField(
              inputFormatters: widget.inputFormatters,
              style: TextStyle(color: currentColor),
              controller: widget.controller,
              keyboardType: widget.textInputType,
              textInputAction: widget.textInputAction,
              enableInteractiveSelection: widget.focusable,
              focusNode:
                  widget.focusable ? widget.currentFocus : DnetDisabledFocusNode(),
              decoration: InputDecoration(
                hintText: widget.hint,
                suffixIcon: getSuffixIcon(),
                fillColor: currentColor,
                labelText: widget.label,
                labelStyle:
                    TextStyle(color: currentColor, fontStyle: FontStyle.italic),
                focusedBorder: border,
                enabledBorder: border,
                border: border,
              ),
              autovalidate: widget.autoValidate,
              validator: (text) {
                final validatorMessage =
                    widget.validator == null ? null : widget.validator(text);
                setHasErrors(validatorMessage != null);
                if (validatorMessage != null) return validatorMessage;
              },
              onFieldSubmitted: widget.onFieldSubmitted ??
                  (term) {
                    if (widget.nextFocus != null) {
                      FocusScope.of(context).requestFocus(widget.nextFocus);
                    }
                  },
              obscureText: widget.isPasswordField && !passwordVisible,
              textCapitalization: widget.textCapitalization,
              maxLength: widget.maxLength != -1 ? widget.maxLength : null,
            ),
          ),
        );
      }
    
      setHasErrors(bool errors) {
        setState(() {
          hasErrors = errors;
        });
      }
    
      setPasswordVisible(bool visible) {
        setState(() {
          passwordVisible = visible;
        });
      }
    
      GestureDetector getSuffixIcon() {
        if (widget.icon != null || widget.isPasswordField) {
          return GestureDetector(
            child: Icon(
              currentIcon,
              color: currentColor,
            ),
            onTap: () {
              if (widget.isPasswordField) setPasswordVisible(!passwordVisible);
            },
          );
        } else {
          return null;
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-05
      相关资源
      最近更新 更多