簡體   English   中英

Flutter - 當文本可見時,文本字段失去焦點

[英]Flutter - Textfield lose focus when text is visible

在我的項目中,我為密碼創建了一個文本字段,並創建了一個顯示和隱藏密碼的方法。 發生的情況是,當我按下圖標顯示文本時,鍵盤和光標消失了,我的意思是,焦點丟失了。

當我按下圖標時,如何使它不會失去焦點? 謝謝

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(),
      ),
    );
  }
}

我無法測試您的代碼,但我有一個自定義文本字段小部件,它允許使用屬性來定義是公共文本字段還是密碼文本字段,也許這對您有所幫助

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;
    }
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM