Flutter中如何添加包含多个Container的水平ListView
Flutter 实现含多个Container的水平列表视图
Flutter 原生ListView组件即可快速实现水平滚动的Container列表,无需额外引入依赖,可直接将列表嵌入现有Stack布局中,具体实现如下:
核心实现逻辑
- 水平滚动列表必须设置明确的高度约束,否则会触发横向滚动组件的布局溢出错误,外层用
SizedBox或固定高度的Container包裹即可 - 给
ListView设置scrollDirection: Axis.horizontal切换为横向滚动模式 - 列表项直接返回自定义样式的
Container,按需配置圆角、边距、背景、内部子组件即可 - 若需要实现卡片吸附轮播效果,可直接复用项目已引入的
carousel_slider,调整viewportFraction参数控制单屏显示的卡片数量,无需额外依赖
可复用的水平列表代码
Widget horizontalCardList(Size size) { // 水平列表必须指定固定高度 return SizedBox( height: 120, width: size.width, child: ListView.builder( scrollDirection: Axis.horizontal, // 左右边距和页面现有文本边距对齐 padding: EdgeInsets.symmetric(horizontal: size.width * 0.08), // 替换为你的实际列表数据长度 itemCount: 6, itemBuilder: (context, index) { return Container( width: 140, // 卡片间距 margin: const EdgeInsets.only(right: 16), // 自定义卡片样式 decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), color: Colors.white.withOpacity(0.2), // 卡片内需要放背景图时打开下面注释 // image: DecorationImage( // image: AssetImage('asset/images/canada${index%3+1}.jpg'), // fit: BoxFit.cover // ) ), // 卡片内部内容按需替换 child: Center( child: Text( '卡片$index', style: const TextStyle(color: Colors.white, fontSize: 16), ), ), ); }, ), ); }
整合到现有项目的完整代码
将列表组件通过Positioned嵌入Stack布局,放在slogan文本下方即可,修改后的完整代码如下:
import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'package:carousel_slider/carousel_slider.dart'; class GetStarted extends StatelessWidget { final List<String> imagesList = [ 'asset/images/canada3.jpg', 'asset/images/canada1.jpg', 'asset/images/canada2.jpg', ]; Widget horizontalCardList(Size size) { return SizedBox( height: 120, width: size.width, child: ListView.builder( scrollDirection: Axis.horizontal, padding: EdgeInsets.symmetric(horizontal: size.width * 0.08), itemCount: 6, itemBuilder: (context, index) { return Container( width: 140, margin: const EdgeInsets.only(right: 16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), color: Colors.white.withOpacity(0.2), ), child: Center( child: Text( '卡片$index', style: const TextStyle(color: Colors.white, fontSize: 16), ), ), ); }, ), ); } @override Widget build(BuildContext context) { final Size size = MediaQuery.of(context).size; return Scaffold( body: Stack( children: [ Container( height: size.height, width: size.width, child: CarouselSlider( options: CarouselOptions( viewportFraction: 1, autoPlay: true, height: size.height, autoPlayInterval: Duration(seconds: 3), ), items: imagesList .map( (item) => Center( child: Image.asset( item, fit: BoxFit.cover, width: size.width, height: size.height, ), ), ) .toList(), ), ), Container( width: size.width, height: size.height, color: Colors.black.withOpacity(0.3), ), Positioned( top: size.height * 0.9, left: size.width * 0.08, child: const Text( 'Login', style: TextStyle( color: Colors.white, fontWeight: FontWeight.w800, fontSize: 15, ), )), Positioned( top: size.height * 0.9, right: size.width * 0.08, child: const Text( 'Skip', style: TextStyle( color: Colors.white, fontWeight: FontWeight.w800, fontSize: 15, ), )), Positioned( top: size.height * 0.6, left: size.width * 0.08, child: const Text( 'Get matched with local pros for\nyour next home project', style: TextStyle( color: Colors.white, fontWeight: FontWeight.w800, fontSize: 20, ), )), // 新增水平列表,放在slogan下方 Positioned( top: size.height * 0.7, left: 0, child: horizontalCardList(size), ) ], ), ); } }
注意事项
- 调整列表高度、卡片宽高、圆角、间距参数时,直接修改对应属性值即可适配设计稿
- 需要卡片点击交互时,给Container外层包裹
GestureDetector或InkWell组件即可绑定点击事件 - 若需要轮播吸附效果,将
ListView替换为已引入的CarouselSlider,设置viewportFraction: 0.7、enableInfiniteScroll: true即可实现一屏多卡的轮播效果
内容的提问来源于stack exchange,提问作者nayo
相关产品推荐
相关产品推荐

