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

Flutter使用TextFormField构建大网格时性能低下问题求助

优化大量TextFormField网格的性能方案

问题场景

展示由大量TextFormField组成的网格时,切换到「Practise」模式(从Text组件切换为TextFormField)需要等待2秒才能完成渲染,设备性能无明显问题,即使仅返回简单的TextFormField()也存在性能瓶颈。

相关代码

Widget cell({int rowIndex = 0, int columnIndex = 0, bool realIndex = false}) {
    return GestureDetector(
      onTap: () {
        if (practising) return;
        setState(() {
          selected['row'] = rowIndex;
          selected['column'] = columnIndex;
        });
      },
      child: Container(
        padding: EdgeInsets.all(realIndex || !practising ? 8 : 5.5),
        decoration: BoxDecoration(
          borderRadius: realIndex
              ? const BorderRadius.only(
                  topLeft: Radius.circular(10),
                  topRight: Radius.circular(10),
                  bottomLeft: Radius.circular(10),
                  bottomRight: Radius.circular(10),
                )
              : columnIndex == 9
                  ? const BorderRadius.only(
                      bottomLeft: Radius.circular(10),
                      bottomRight: Radius.circular(10),
                    )
                  : null,
          color: selected['column'] == columnIndex
              ? Helpers.hexToColor(colors[rowIndex])
              : null,
        ),
        child: Center(
          child: !realIndex && practising
              ? SizedBox(
                  height: 25,
                  child: TextFormField(
                    controller: textControllers[rowIndex][columnIndex],
                    keyboardType: TextInputType.number,
                    showCursor: false,
                    decoration: InputDecoration(
                      contentPadding: const EdgeInsets.symmetric(
                          horizontal: 0, vertical: 0),
                      fillColor: showColors
                          ? true
                              ? Colors.green
                              : Colors.red
                          : null,
                      filled: showColors,
                      border: const OutlineInputBorder(),
                      enabledBorder: OutlineInputBorder(
                        borderSide: BorderSide(
                          width: 2,
                          color: showColors
                              ? true
                                  ? Colors.green[800]!
                                  : Colors.red[800]!
                              : Colors.grey,
                        ),
                      ),
                    ),
                    textAlign: TextAlign.center,
                  ),
                )
              : Text(
                  ((rowIndex + 1) * (columnIndex + 1)).toString() +
                      (realIndex ? 'x' : ''),
                  style: TextStyle(
                    fontWeight: realIndex ? FontWeight.bold : null,
                    color:
                        selected['column'] == columnIndex ? Colors.white : null,
                  ),
                ),
        ),
      ),
    );
  }

具体优化方案

1. 改用懒加载组件渲染网格

不要一次性创建所有TextFormField,使用GridView.builder(或ListView.builder)代替直接生成所有子组件。懒加载只会渲染当前可见区域的组件,大幅减少初始渲染的组件数量,提升切换速度。

示例:

GridView.builder(
  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 10, // 你的列数
  ),
  itemCount: totalCells, // 总单元格数
  itemBuilder: (context, index) {
    int rowIndex = index ~/ 10;
    int columnIndex = index % 10;
    return cell(rowIndex: rowIndex, columnIndex: columnIndex);
  },
)

2. 缓存InputDecoration实例

每次build时创建新的InputDecoration会产生额外的对象开销,把通用的装饰实例缓存为静态常量,减少重复创建:

// 在组件类中定义静态常量
static const InputDecoration _textFieldDecoration = InputDecoration(
  contentPadding: EdgeInsets.symmetric(horizontal: 0, vertical: 0),
  border: OutlineInputBorder(),
);

// 在TextFormField中使用
decoration: _textFieldDecoration.copyWith(
  fillColor: showColors ? (true ? Colors.green : Colors.red) : null,
  filled: showColors,
  enabledBorder: OutlineInputBorder(
    borderSide: BorderSide(
      width: 2,
      color: showColors ? (true ? Colors.green[800]! : Colors.red[800]!) : Colors.grey,
    ),
  ),
),

3. 拆分独立组件,减少重建范围

把cell函数拆分为独立的StatefulWidget(比如GridCell),并使用AutomaticKeepAliveClientMixin保持组件状态,避免切换或滚动时不必要的重建。同时,将practising、showColors等状态通过ValueListenableBuilder监听,只在状态变化时更新需要的部分,而不是全量重建整个网格。

4. 禁用TextFormField不必要的特性

关闭自动校正、输入建议等不需要的功能,减少TextFormField的初始化开销:

TextFormField(
  autocorrect: false,
  enableSuggestions: false,
  // ... 其他配置
)

5. 优化State更新方式

不要使用setState更新整个页面状态,改用ValueNotifier、ChangeNotifier等局部状态管理方式,只通知需要更新的组件,避免全量重建。比如把practising、showColors、selected都改成ValueNotifier,通过ValueListenableBuilder监听变化。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 02:24:54