如何基于列表长度优化StaggeredGridView布局并减少代码冗余?
优化Flutter StaggeredGrid布局代码,减少冗余
你的现有代码逻辑可行,但存在大量重复的Tile创建代码,我们可以通过抽象布局配置+复用通用逻辑的方式大幅减少冗余,同时保持逻辑清晰。
核心优化思路
- 把不同
itemCount对应的每个Tile的布局参数(跨轴单元格数、主轴单元格数、圆角配置)抽成结构化的配置数据 - 根据
itemCount选择对应的配置列表,循环生成普通Tile - 单独封装"All +" Tile的逻辑,避免重复编写容器和手势检测器代码
优化后的完整代码
import 'package:flutter/material.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; // 定义Tile的配置数据结构,统一管理布局参数 class TileConfig { final int crossAxisCount; final int mainAxisCount; final BorderRadius borderRadius; final bool isAllTile; TileConfig({ required this.crossAxisCount, required this.mainAxisCount, required this.borderRadius, this.isAllTile = false, }); } StaggeredGrid buildGrid(List<int> tileNumbers) { final itemCount = tileNumbers.length; List<TileConfig> configs = []; // 根据itemCount匹配对应的布局配置 if (itemCount == 1) { configs = [ TileConfig( crossAxisCount: 4, mainAxisCount: 2, borderRadius: BorderRadius.circular(10), ), ]; } else if (itemCount == 2) { configs = [ TileConfig( crossAxisCount: 2, mainAxisCount: 2, borderRadius: const BorderRadius.only( topLeft: Radius.circular(10), bottomLeft: Radius.circular(10), ), ), TileConfig( crossAxisCount: 2, mainAxisCount: 2, borderRadius: const BorderRadius.only( topRight: Radius.circular(10), bottomRight: Radius.circular(10), ), ), ]; } else if (itemCount == 3) { configs = [ TileConfig( crossAxisCount: 2, mainAxisCount: 2, borderRadius: const BorderRadius.only( topLeft: Radius.circular(10), bottomLeft: Radius.circular(10), ), ), TileConfig( crossAxisCount: 2, mainAxisCount: 1, borderRadius: const BorderRadius.only( topRight: Radius.circular(10), bottomRight: Radius.circular(10), bottomLeft: Radius.circular(10), ), ), TileConfig( crossAxisCount: 2, mainAxisCount: 1, borderRadius: const BorderRadius.only( topRight: Radius.circular(10), topLeft: Radius.circular(10), bottomLeft: Radius.circular(10), ), ), ]; } else { // itemCount ==4 或 >=4 的基础配置 configs = [ TileConfig( crossAxisCount: 2, mainAxisCount: 2, borderRadius: const BorderRadius.only( topLeft: Radius.circular(10), bottomLeft: Radius.circular(10), ), ), TileConfig( crossAxisCount: 2, mainAxisCount: 1, borderRadius: const BorderRadius.only( topRight: Radius.circular(10), bottomRight: Radius.circular(10), bottomLeft: Radius.circular(10), ), ), TileConfig( crossAxisCount: 1, mainAxisCount: 1, borderRadius: BorderRadius.circular(10), ), ]; // 处理末尾Tile:如果是>=4,替换为All+,否则用普通Tile configs.add(itemCount >=4 ? TileConfig( crossAxisCount: 1, mainAxisCount: 1, borderRadius: const BorderRadius.only( topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), bottomRight: Radius.circular(20), ), isAllTile: true, ) : TileConfig( crossAxisCount: 1, mainAxisCount: 1, borderRadius: const BorderRadius.only( topLeft: Radius.circular(10), topRight: Radius.circular(10), bottomLeft: Radius.circular(10), ), ) ); } // 循环生成所有Tile final tiles = <StaggeredGridTile>[]; for (int i=0; i<configs.length; i++) { final config = configs[i]; tiles.add( config.isAllTile ? _buildAllTile(config) : _buildNormalTile(config, tileNumbers[i]) ); } return StaggeredGrid.count( crossAxisCount: 4, mainAxisSpacing: 4, crossAxisSpacing: 4, children: tiles, ); } // 复用的普通Tile构建方法 StaggeredGridTile _buildNormalTile(TileConfig config, int tileNumber) { return StaggeredGridTile.count( crossAxisCellCount: config.crossAxisCount, mainAxisCellCount: config.mainAxisCount, child: Container( decoration: BoxDecoration(borderRadius: config.borderRadius), child: Center(child: Text(tileNumber.toString())), ), ); } // 单独封装All+ Tile,便于后续修改样式或添加交互 StaggeredGridTile _buildAllTile(TileConfig config) { return StaggeredGridTile.count( crossAxisCellCount: config.crossAxisCount, mainAxisCellCount: config.mainAxisCount, child: GestureDetector( onTap: () { // 可在此添加All+的点击逻辑 }, child: Container( decoration: BoxDecoration(borderRadius: config.borderRadius), child: const Center(child: Text("All +")), ), ), ); }
优化点说明
- 抽象配置数据:用
TileConfig类统一管理每个Tile的布局参数,避免重复传递大量零散参数 - 减少重复代码:把重复的Tile创建逻辑拆分为
_buildNormalTile和_buildAllTile两个复用方法,避免大量重复的StaggeredGridTile.count调用 - 简化分支逻辑:将不同
itemCount的布局规则转化为配置列表,减少嵌套的if-else层级,逻辑更清晰 - 统一处理All+:单独封装All+ Tile的构建逻辑,便于后续修改样式或添加点击事件
内容的提问来源于stack exchange,提问作者Spencer
相关产品推荐
相关产品推荐

