dart 抖动:使用ThemeData的边框内的TextField或TextFormField标签

hsgswve4  于 2023-02-27  发布在  其他
关注(0)|答案(2)|浏览(177)

TextField小工具处于活动状态时,如何使TextField标签浮动到顶部,但仍保持在TextField边界内(而不是边缘)?
我想要的例子:

变成


这个
ThemeData上使用inputDecorationTheme是否可能?或者我必须制作一个 Package 器小部件来完成这一任务?
会非常喜欢从应用程序范围的ThemeData控制它

ql3eal8s

ql3eal8s1#

不幸的是,我不知道如何用默认的工具,但我用另一种方式做,可能会对你有帮助。
1.为FocusNode和小工具内的边框颜色创建变量:

// Use it to change color for border when textFiled in focus
FocusNode _focusNode = FocusNode();

// Color for border
Color _borderColor = Colors.grey;

1.在initState内部为textField创建侦听器,如果textField将成为焦点,则将边框颜色更改为橙子,否则更改为灰色:

@override
void initState() {
  super.initState();
  // Change color for border if focus was changed
  _focusNode.addListener(() {
    setState(() {
      _borderColor = _focusNode.hasFocus ? Colors.orange : Colors.grey;
    });
  });
}

1.创建带有textField边框的Container,添加focusNode并将装饰设置为textField

Container(
  decoration: BoxDecoration(
    border: Border.all(color: _borderColor),
    borderRadius: BorderRadius.circular(4),
  ),
  child: TextField(
    focusNode: _focusNode,
    style: TextStyle(color: Colors.grey),
    keyboardType: TextInputType.number,
    decoration: InputDecoration(
      contentPadding: EdgeInsets.zero,
      border: InputBorder.none,
      labelText: "Amount",
      prefixIconConstraints: BoxConstraints(minWidth: 0, minHeight: 0),
      prefixIcon: Padding(
        padding: EdgeInsets.symmetric(vertical: 18, horizontal: 8),
        child: Text("₦", style: TextStyle(fontSize: 16, color: Colors.grey)),
      ),
    ),
  ),
),

1.请不要忘记致电dispose获取focusNode

@override
void dispose() {
  _focusNode.dispose();
  super.dispose();
}

完整代码:

class TextFieldDesignPage extends StatefulWidget {
  TextFieldDesignPage({Key? key}) : super(key: key);

  @override
  _TextFieldDesignPageState createState() => _TextFieldDesignPageState();
}

class _TextFieldDesignPageState extends State<TextFieldDesignPage> {
  // Use it to change color for border when textFiled in focus
  FocusNode _focusNode = FocusNode();

  // Color for border
  Color _borderColor = Colors.grey;

  @override
  void initState() {
    super.initState();
    // Change color for border if focus was changed
    _focusNode.addListener(() {
      setState(() {
        _borderColor = _focusNode.hasFocus ? Colors.orange : Colors.grey;
      });
    });
  }

  @override
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          margin: EdgeInsets.all(8),
          decoration: BoxDecoration(
            border: Border.all(color: _borderColor),
            borderRadius: BorderRadius.circular(4),
          ),
          child: TextField(
            focusNode: _focusNode,
            style: TextStyle(color: Colors.grey),
            keyboardType: TextInputType.number,
            decoration: InputDecoration(
              contentPadding: EdgeInsets.zero,
              border: InputBorder.none,
              labelText: "Amount",
              prefixIconConstraints: BoxConstraints(minWidth: 0, minHeight: 0),
              prefixIcon: Padding(
                padding: EdgeInsets.symmetric(vertical: 18, horizontal: 8),
                child: Text("₦", style: TextStyle(fontSize: 16, color: Colors.grey)),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

结果:

jtw3ybtb

jtw3ybtb2#

class MyInputTextField extends StatefulWidget {
  final String? title;
  final String? helperText;
  final bool isSecure;
  final int maxLength;
  final String? hint;
  final TextInputType? inputType;
  final String? initValue;
  final Color? backColor;
  final Widget? suffix;
  final Widget? prefix;
  final TextEditingController? textEditingController;
  final String? Function(String? value)? validator;
  final Function(String)? onTextChanged;
  final Function(String)? onSaved;
  List<TextInputFormatter>? inputFormatters;

  static const int MAX_LENGTH = 500;

  MyInputTextField({
    this.title,
    this.hint,
    this.helperText,
    this.inputType,
    this.initValue = "",
    this.isSecure = false,
    this.textEditingController,
    this.validator,
    this.maxLength = MAX_LENGTH,
    this.onTextChanged,
    this.onSaved,
    this.inputFormatters,
    this.backColor,
    this.suffix,
    this.prefix,
  });

  @override
  _MyInputTextFieldState createState() => _MyInputTextFieldState();
}

class _MyInputTextFieldState extends State<MyInputTextField> {
  late bool _passwordVisibility;
  late ThemeData theme;

  FocusNode _focusNode = FocusNode();

  Color _borderColor = getColors().primaryVariant;
  double _borderSize = 1;

  @override
  void initState() {
    super.initState();
    _passwordVisibility = !widget.isSecure;
    widget.textEditingController?.text = widget.initValue ?? "";

    _focusNode.addListener(() {
      setState(() {
        _borderSize = _focusNode.hasFocus ? 1.7 : 1;
      });
    });
  }

  @override
  void didChangeDependencies() {
    theme = Theme.of(context);
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Container(
          height: 55,
          decoration: BoxDecoration(
            border: Border.all(color: _borderColor, width: _borderSize),
            borderRadius: BorderRadius.circular(AppDimens.radiusSmall),
          ),
        ),
        Padding(
          padding: EdgeInsets.symmetric(horizontal: 12, vertical: 4),
          child: TextFormField(
            focusNode: _focusNode,
            controller: widget.textEditingController,
            autocorrect: false,
            obscureText: !_passwordVisibility,
            keyboardType: widget.inputType,
            cursorColor: Colors.white,
            validator: (value) {
              String? f = widget.validator?.call(value);
              setState(() {
                _borderColor = f != null ? getColors().redError : getColors().primaryVariant;
              });
              return f;
            },
            style: theme.textTheme.bodyText1,
            maxLength: widget.maxLength,
            inputFormatters: widget.inputFormatters,
            maxLines: 1,
            onChanged: (text) {
              widget.onTextChanged?.call(text);
            },
            decoration: InputDecoration(
              counterText: "",
              hintStyle: theme.textTheme.subtitle1,
              floatingLabelStyle: theme.textTheme.headline6?.copyWith(color: getColors().textSubtitle),
              labelText: widget.title,
              helperText: widget.helperText,
              suffixIcon: getSuffixIcon(),
              prefixIcon: widget.prefix,
              contentPadding: EdgeInsets.zero,
              border: InputBorder.none,
            ),
          ),
        )
      ],
    );
  }

  Widget? getSuffixIcon() {
    return widget.isSecure ? getPasswordSuffixIcon() : widget.suffix;
  }

  Widget? getPasswordSuffixIcon() {
    return IconButton(
      hoverColor: Colors.transparent,
      focusColor: Colors.transparent,
      splashColor: Colors.transparent,
      padding: EdgeInsets.zero,
      icon: _passwordVisibility ? Icon(AppIcons.password_eye) : Icon(AppIcons.password_eye_blind),
      color: Colors.white,
      onPressed: () {
        setState(() {
          _passwordVisibility = !_passwordVisibility;
        });
      },
    );
  }

  @override
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }
}

相关问题