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

如何在Flutter中实现可横向滚动交错网格并循环加载API图片?

Flutter实现横向滚动循环网格+API图片加载方案

核心实现步骤

  • 用SingleChildScrollView实现横向滚动容器
  • 预定义固定的Tile尺寸配置列表,通过取模逻辑实现循环布局
  • 动态绑定API返回的图片链接,处理图片加载/错误状态

完整代码示例

1. 定义配置与模拟API数据

// 循环复用的Tile尺寸配置(对应你原代码中的6种Tile规格)
final List<Map<String, int>> tileLayouts = [
  {'crossCells': 1, 'mainCells': 2},
  {'crossCells': 1, 'mainCells': 1},
  {'crossCells': 1, 'mainCells': 1},
  {'crossCells': 1, 'mainCells': 1},
  {'crossCells': 1, 'mainCells': 2},
  {'crossCells': 2, 'mainCells': 1},
];

// 模拟API返回的图片链接(实际项目替换为真实接口请求)
Future<List<String>> fetchImages() async {
  // 这里写你的API请求逻辑,比如用http包获取图片列表
  await Future.delayed(const Duration(seconds: 1));
  return [
    'https://picsum.photos/200/300',
    'https://picsum.photos/200/200',
    'https://picsum.photos/200/200',
    'https://picsum.photos/200/200',
    'https://picsum.photos/200/300',
    'https://picsum.photos/400/200',
    'https://picsum.photos/200/300',
    'https://picsum.photos/200/200',
    'https://picsum.photos/200/200',
  ];
}

2. 横向滚动网格UI

FutureBuilder<List<String>>(
  future: fetchImages(),
  builder: (context, snapshot) {
    // 加载中状态
    if (snapshot.connectionState == ConnectionState.waiting) {
      return const SizedBox(
        height: 210,
        child: Center(child: CircularProgressIndicator()),
      );
    }
    // 加载错误状态
    if (snapshot.hasError || snapshot.data == null) {
      return const SizedBox(
        height: 210,
        child: Center(child: Text('图片加载失败')),
      );
    }

    final imageList = snapshot.data!;
    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      padding: const EdgeInsets.symmetric(horizontal: 16),
      child: SizedBox(
        // 网格总高度:最大mainCells(2)*单格高度(100) + 间距(4*2)
        height: 208,
        child: StaggeredGrid.count(
          crossAxisCount: 3,
          mainAxisSpacing: 4,
          crossAxisSpacing: 4,
          children: List.generate(imageList.length, (index) {
            // 循环取Tile配置
            final layout = tileLayouts[index % tileLayouts.length];
            final imageUrl = imageList[index];

            return StaggeredGridTile.count(
              crossAxisCellCount: layout['crossCells']!,
              mainAxisCellCount: layout['mainCells']!,
              child: Card(
                elevation: 50,
                shadowColor: Colors.black,
                borderRadius: BorderRadius.circular(8),
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(8),
                  child: Image.network(
                    imageUrl,
                    fit: BoxFit.cover,
                    // 加载中占位
                    loadingBuilder: (context, child, progress) {
                      if (progress == null) return child;
                      return const Center(child: CircularProgressIndicator(strokeWidth: 2));
                    },
                    // 加载失败占位
                    errorBuilder: (context, error, stack) {
                      return const Center(child: Icon(Icons.broken_image, color: Colors.grey));
                    },
                  ),
                ),
              ),
            );
          }),
        ),
      ),
    );
  },
)

关键细节说明

  • 横向滚动:外层SingleChildScrollView设置scrollDirection: Axis.horizontal,配合SizedBox固定网格高度,避免布局错乱。
  • 循环布局:通过index % tileLayouts.length重复使用预定义的6种Tile规格,实现无限循环的网格样式。
  • 图片加载:利用Image.network的loadingBuilder和errorBuilder处理加载状态,提升用户体验;如需图片缓存,可替换为CachedNetworkImage(需添加对应依赖)。
  • 固定尺寸:通过SizedBox高度和Tile的mainAxisCellCount控制卡片尺寸,可根据需求调整单格高度(示例中设为100)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 02:05:16