当TextField小工具处于活动状态时,如何使TextField标签浮动到顶部,但仍保持在TextField边界内(而不是边缘)?我想要的例子:
TextField
变成
这个在ThemeData上使用inputDecorationTheme是否可能?或者我必须制作一个 Package 器小部件来完成这一任务?会非常喜欢从应用程序范围的ThemeData控制它
ThemeData
inputDecorationTheme
ql3eal8s1#
不幸的是,我不知道如何用默认的工具,但我用另一种方式做,可能会对你有帮助。1.为FocusNode和小工具内的边框颜色创建变量:
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将成为焦点,则将边框颜色更改为橙子,否则更改为灰色:
initState
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
focusNode
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:
dispose
@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)), ), ), ), ), ), ); } }
结果:
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(); } }
2条答案
按热度按时间ql3eal8s1#
不幸的是,我不知道如何用默认的工具,但我用另一种方式做,可能会对你有帮助。
1.为
FocusNode
和小工具内的边框颜色创建变量:1.在
initState
内部为textField
创建侦听器,如果textField
将成为焦点,则将边框颜色更改为橙子,否则更改为灰色:1.创建带有
textField
边框的Container
,添加focusNode
并将装饰设置为textField
:1.请不要忘记致电
dispose
获取focusNode
:完整代码:
结果:
jtw3ybtb2#