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

如何基于列表长度优化StaggeredGridView布局并减少代码冗余?

优化Flutter StaggeredGrid布局代码,减少冗余

你的现有代码逻辑可行,但存在大量重复的Tile创建代码,我们可以通过抽象布局配置+复用通用逻辑的方式大幅减少冗余,同时保持逻辑清晰。

核心优化思路

  1. 把不同itemCount对应的每个Tile的布局参数(跨轴单元格数、主轴单元格数、圆角配置)抽成结构化的配置数据
  2. 根据itemCount选择对应的配置列表,循环生成普通Tile
  3. 单独封装"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 +")),
      ),
    ),
  );
}

优化点说明

  1. 抽象配置数据:用TileConfig类统一管理每个Tile的布局参数,避免重复传递大量零散参数
  2. 减少重复代码:把重复的Tile创建逻辑拆分为_buildNormalTile和_buildAllTile两个复用方法,避免大量重复的StaggeredGridTile.count调用
  3. 简化分支逻辑:将不同itemCount的布局规则转化为配置列表,减少嵌套的if-else层级,逻辑更清晰
  4. 统一处理All+:单独封装All+ Tile的构建逻辑,便于后续修改样式或添加点击事件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 04:18:11