即使在文本字段中输入文本,我也希望提示文本保留:
但是如果我以简单的方式给 TextField 一些类似“hintText:”的东西,当输入 TextField 时提示文本就会消失:
我应该怎么做才能即使在文本字段中输入值时提示文本也不会消失?
。 。 。 我尝试了以下方法:
我。我尝试使用后缀小部件。但它是从 TextField 的末尾出现的。 (如果可以让后缀小部件出现在文本后面,我想问题就解决了。) :
二.显然 Prefix Widget 在这里无法提供帮助:
欢迎任何答案,谢谢。
您可以使用在文本字段顶部可见的标签,并且您可以简单地添加以下行的提示:
floatingLabelBehavior: FloatingLabelBehavior.always
完整示例如下
TextFormField(
controller: textController,
style: theme.textTheme.bodyText2,
keyboardType: keyboardType ?? TextInputType.number,
enableInteractiveSelection: false,
decoration: InputDecoration(
labelText: labelText,
labelStyle: theme.textTheme.headline6,
suffixText: suffixText ?? '',
border: OutlineInputBorder(
borderSide:
BorderSide(color: theme.textTheme.bodyText2.color, width: 2),
),
hintText: '0.0',
floatingLabelBehavior: FloatingLabelBehavior.always),
validator: (value) {
if (value.isEmpty) {
return 'Please enter some text';
}
return null;
},
onChanged: (String text) => onChange(text),
);
答案:
然后我研究了一下,发现 Telegram Messenger 使用了更复杂的方法,在
Canvas
上进行自定义渲染,并通过调整提示文本的不透明度和位置来为提示文本设置动画。您可以在此处查看实施情况。
但我使用了一个更简单的解决方案,带有
Stack
和 monospace
字体:
这是一个简单的例子:
import 'package:flutter/material.dart';
import 'package:mask_text_input_formatter/mask_text_input_formatter.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.all(18),
child: CustomMaskedTextField(
mask: '--- --- ----',
style: const TextStyle(fontSize: 24, letterSpacing: 1.0),
decoration: const InputDecoration(border: OutlineInputBorder()),
onChanged: (value) => print('Current value: $value'),
),
),
),
),
);
}
}
class CustomMaskedTextField extends StatefulWidget {
final String mask;
final TextStyle? style;
final InputDecoration? decoration;
final ValueChanged<String>? onChanged;
const CustomMaskedTextField({
super.key,
required this.mask,
this.style,
this.decoration,
this.onChanged,
});
@override
_CustomMaskedTextFieldState createState() => _CustomMaskedTextFieldState();
}
class _CustomMaskedTextFieldState extends State<CustomMaskedTextField> {
final _inputController = TextEditingController();
final _hintController = TextEditingController();
late final MaskTextInputFormatter maskFormatter;
@override
void initState() {
super.initState();
maskFormatter = MaskTextInputFormatter(mask: widget.mask, filter: {"#": RegExp(r'[0-9]')});
_inputController.addListener(_updateHintText);
_updateHintText();
}
void _updateHintText() {
final text = _inputController.text;
final remainingMask = widget.mask.substring(text.length);
_hintController.text = text + remainingMask;
widget.onChanged?.call(text);
}
@override
void dispose() {
_inputController.removeListener(_updateHintText);
_inputController.dispose();
_hintController.dispose();
super.dispose();
}
TextStyle get _baseStyle => widget.style?.copyWith(fontFamily: 'Courier') ?? const TextStyle(fontFamily: 'Courier');
@override
Widget build(BuildContext context) {
return Stack(
children: [
AbsorbPointer(
child: TextField(
controller: _hintController,
enabled: false,
style: _baseStyle.copyWith(color: Colors.grey),
decoration: widget.decoration,
),
),
TextField(
controller: _inputController,
inputFormatters: [maskFormatter],
style: _baseStyle.copyWith(color: Colors.black),
decoration: widget.decoration,
),
],
);
}
}
随时根据您的用例进行定制!