You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让ListView.builder中每行TextField高度统一为该行最大高度

解决Flutter中一行内TextField同步高度的问题

你的问题核心是让同一行内的所有TextField在任意一个高度变化时,同步调整为该行的最大高度。使用IntrinsicHeight之所以无效,是因为它会强制子组件先确定高度再布局,而TextField设置maxLines: null时需要动态扩展高度,IntrinsicHeight的约束会限制其正常更新。

下面是可行的解决方案,通过监听文本变化并同步高度实现:

实现思路

  1. 为每一行创建独立的状态管理组件,避免行之间的状态干扰。
  2. 为每个TextField绑定GlobalKey,用于获取其实际渲染高度。
  3. 监听每个TextField的文本变化,在布局更新后计算该行的最大高度。
  4. 将所有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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 01:32:59