如何让ListView.builder中每行TextField高度统一为该行最大高度
解决Flutter中一行内TextField同步高度的问题
你的问题核心是让同一行内的所有TextField在任意一个高度变化时,同步调整为该行的最大高度。使用IntrinsicHeight之所以无效,是因为它会强制子组件先确定高度再布局,而TextField设置maxLines: null时需要动态扩展高度,IntrinsicHeight的约束会限制其正常更新。
下面是可行的解决方案,通过监听文本变化并同步高度实现:
实现思路
- 为每一行创建独立的状态管理组件,避免行之间的状态干扰。
- 为每个
TextField绑定GlobalKey,用于获取其实际渲染高度。 - 监听每个
TextField的文本变化,在布局更新后计算该行的最大高度。 - 将所有
TextField的父容器高度设置为最大高度,并开启TextField的expands属性,使其填充父容器高度。
完整代码示例
import 'package:flutter/material.dart'; class ListTest extends StatefulWidget { const ListTest({Key? key}) : super(key: key); @override State<ListTest> createState() => _ListTestState(); } class _ListTestState extends State<ListTest> { @override Widget build(BuildContext context) { return Scaffold( body: Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 30), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text("Welcome"), Expanded( child: ListView.builder( padding: EdgeInsets.zero, itemCount: 10, itemBuilder: (c, i) { return const RowTextField(); }, ), ), ], ), ), ); } } class RowTextField extends StatefulWidget { const RowTextField({Key? key}) : super(key: key); @override State<RowTextField> createState() => _RowTextFieldState(); } class _RowTextFieldState extends State<RowTextField> { final List<TextEditingController> _controllers = List.generate(5, (_) => TextEditingController()); final List<GlobalKey> _textFieldKeys = List.generate(5, (_) => GlobalKey()); double _maxHeight = 0; @override void initState() { super.initState(); // 监听每个文本控制器的内容变化 for (var controller in _controllers) { controller.addListener(_updateMaxHeight); } } @override void dispose() { // 清理资源 for (var controller in _controllers) { controller.removeListener(_updateMaxHeight); controller.dispose(); } super.dispose(); } void _updateMaxHeight() { // 等待布局更新后再计算高度 WidgetsBinding.instance.addPostFrameCallback((_) { double newMaxHeight = 0; for (var key in _textFieldKeys) { final renderBox = key.currentContext?.findRenderObject() as RenderBox?; if (renderBox != null) { final height = renderBox.size.height; if (height > newMaxHeight) { newMaxHeight = height; } } } if (newMaxHeight != _maxHeight) { setState(() { _maxHeight = newMaxHeight; }); } }); } final InputDecoration _decoration = InputDecoration( border: _border, focusedBorder: _border, enabledBorder: _border, ); static final OutlineInputBorder _border = OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: const BorderSide(color: Colors.grey), ); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Row( children: [ const SizedBox(width: 30), ...List.generate(5, (index) { return Expanded( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 4.0), child: Container( height: _maxHeight == 0 ? null : _maxHeight, child: TextField( key: _textFieldKeys[index], controller: _controllers[index], maxLines: null, expands: _maxHeight != 0, decoration: _decoration, ), ), ), ); }), ], ), ); } }
代码说明
- 独立状态管理:
RowTextField作为每一行的独立组件,管理该行所有TextField的状态,避免行之间的高度干扰。 - 高度监听:通过
GlobalKey获取TextField的渲染高度,在文本变化后计算最大值。 - 同步高度:将所有
TextField的父容器高度设置为最大高度,expands: true确保TextField填充整个容器高度,实现同步效果。
内容的提问来源于stack exchange,提问作者muhammed jasir
相关产品推荐
相关产品推荐

