如何在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
相关产品推荐
相关产品推荐

