If you want to allocate a Fixed Lines Textfield, you can try the below widget:
style is required because it uses the text height to calculate the line
numberOfLines is the line number of underlines that need to be generated.
class UnderlineTextField extends StatelessWidget {
const UnderlineTextField({
required this.style,
required this.numberOfLines,
this.controller,
this.decoration = const InputDecoration(isDense: true),
this.keyboardType,
this.maxLines = 1,
this.minLines,
Key? key,
}) : super(key: key);
final TextEditingController? controller;
final InputDecoration? decoration;
final TextInputType? keyboardType;
final int? maxLines;
final int? minLines;
final int lines;
final TextStyle style;
@override
Widget build(BuildContext context) {
final textHeight = style.height ?? 20;
return Stack(
children: [
TextField(
style: style,
controller: controller,
decoration: decoration,
keyboardType: keyboardType,
maxLines: maxLines,
minLines: minLines,
),
Positioned.fill(
child: Padding(
padding: const EdgeInsets.only(top: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: List.generate(
numberOfLines,
(index) => Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(height: textHeight),
const Divider(height: 1, thickness: 1),
],
),
),
),
),
),
],
);
}
}
If you want to let the underline auto-added with the text content, you may need to add the listener inside the text controller and try to use TextPainter to calculate the number of lines:
... (inside the UnderlineTextField)
double maxWidth = 0;
controller?.addListener(() {
final text = controller?.text ?? '';
final textPainter = TextPainter(
text: TextSpan(text: text, style: style),
maxLines: maxLines,
textDirection: TextDirection.ltr,
);
textPainter.layout(maxWidth: maxWidth);
final numberOfLines = textPainter.computeLineMetrics().length;
});
return LayoutBuilder(
builder: (_, constrinat) {
maxWidth = constrinat.maxWidth;
...