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

Flutter ListView中多行TextField高度变化后ListTile位置不更新问题求解

Flutter多行TextField后ListTile错位问题解决方案

问题根因

该错位问题是Flutter ListView的默认布局优化机制导致的:当TextField高度随输入换行变化时,ListView仅触发了子组件的内容更新,没有完整重新计算所有子组件的绘制位置,因此ListTile的背景色绘制区域仍停留在旧位置,而内部的文字、图标等子元素正常更新,就出现了视觉上的错位,滑动ListView时触发了完整重绘才会恢复正常。

可用解决方案

  • 方案1:用SingleChildScrollView嵌套Column替代ListView,适合子组件数量少的场景,完全规避ListView的子组件缓存优化,不会出现错位问题,代码示例如下:
@override
Widget build(BuildContext context) {
  final scrollView = SingleChildScrollView(
    child: Column(
      children: [
        TextField(maxLines: null),
        SizedBox(height: 50, child: ColoredBox(color: Colors.yellow,child: Text("Tile1"),) ),
        ListTile(tileColor: Colors.blueGrey,title: Text("Tile1"),),
        ListTile(tileColor: Colors.blueGrey,title: Icon(Icons.looks_two_rounded),)
      ],
    ),
  );
  return Scaffold(backgroundColor: Color(0xdcdcffff), body: Center(child: scrollView));
}
  • 方案2:保留ListView的使用,关闭其默认的子组件保活优化,构造ListView时添加addAutomaticKeepAlives: false参数即可,代码示例如下:
@override
Widget build(BuildContext context) {
  ListView l = new ListView(
    addAutomaticKeepAlives: false,
    children: [
      TextField(maxLines: null),
      SizedBox(height: 50, child: ColoredBox(color: Colors.yellow,child: Text("Tile1"),) ),
      ListTile(tileColor: Colors.blueGrey,title: Text("Tile1"),),
      ListTile(tileColor: Colors.blueGrey,title: Icon(Icons.looks_two_rounded),)
    ]);
  return Scaffold(backgroundColor: Color(0xdcdcffff), body: Center(child: l));
}
  • 方案3:如果需要保留ListView的懒加载能力,可给TextField添加onChanged回调,每次输入时触发页面重绘,强制ListView重新计算布局:
TextField(
  maxLines: null,
  onChanged: (_) => setState(() {}),
)

内容的提问来源于stack exchange,提问作者OneUsernamePlease

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 10:06:02