如何在Flutter中实现API数据源的垂直Carousel Slider?
Flutter 垂直轮播滑块(API数据驱动)
1. 添加依赖
先在pubspec.yaml里加入实现轮播和API请求的依赖:
dependencies: flutter: sdk: flutter carousel_slider: ^4.2.1 # 建议用最新版本 http: ^1.1.0 # 用于发起API请求
执行flutter pub get完成依赖安装。
2. 处理API数据模型与请求
先定义对应API返回结构的数据模型,再写请求函数:
// 轮播项数据模型 class SliderItem { final String title; final String desc; final String imageUrl; SliderItem({required this.title, required this.desc, required this.imageUrl}); // 从JSON转模型 factory SliderItem.fromJson(Map<String, dynamic> json) { return SliderItem( title: json['title'] ?? '', desc: json['description'] ?? '', imageUrl: json['image_url'] ?? '', ); } } // 获取API数据的函数 Future<List<SliderItem>> getSliderData() async { final response = await http.get(Uri.parse('你的API接口地址')); if (response.statusCode == 200) { List<dynamic> rawData = json.decode(response.body); return rawData.map((item) => SliderItem.fromJson(item)).toList(); } else { throw Exception('加载轮播数据失败'); } }
3. 实现垂直轮播组件
结合FutureBuilder处理API数据的加载状态,用CarouselSlider实现垂直滚动:
class VerticalCarouselSlider extends StatefulWidget { const VerticalCarouselSlider({super.key}); @override State<VerticalCarouselSlider> createState() => _VerticalCarouselSliderState(); } class _VerticalCarouselSliderState extends State<VerticalCarouselSlider> { late Future<List<SliderItem>> _sliderDataFuture; @override void initState() { super.initState(); _sliderDataFuture = getSliderData(); } @override Widget build(BuildContext context) { return FutureBuilder<List<SliderItem>>( future: _sliderDataFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } else if (snapshot.hasError) { return Center(child: Text('出错了:${snapshot.error}')); } else if (snapshot.data == null || snapshot.data!.isEmpty) { return const Center(child: Text('暂无轮播内容')); } else { final sliderItems = snapshot.data!; return CarouselSlider( options: CarouselOptions( scrollDirection: Axis.vertical, // 核心:设置垂直滚动 autoPlay: true, // 可选:自动轮播 autoPlayInterval: const Duration(seconds: 3), viewportFraction: 0.75, // 可见区域占比 enlargeCenterPage: true, // 居中项放大效果 ), items: sliderItems.map((item) { return Builder( builder: (context) { return Container( width: MediaQuery.of(context).size.width, margin: const EdgeInsets.symmetric(vertical: 8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: const [ BoxShadow(color: Colors.black12, blurRadius: 6, offset: Offset(0,2)) ] ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 轮播图 ClipRRect( borderRadius: const BorderRadius.vertical(top: Radius.circular(12)), child: Image.network( item.imageUrl, height: 180, width: double.infinity, fit: BoxFit.cover, ), ), // 文字内容 Padding( padding: const EdgeInsets.all(14), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( item.title, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600), ), const SizedBox(height: 6), Text( item.desc, style: const TextStyle(fontSize: 14, color: Colors.grey), maxLines: 2, overflow: TextOverflow.ellipsis, ), ], ), ), ], ), ); }, ); }).toList(), ); } }, ); } }
4. 在页面中使用组件
直接把轮播组件放到你的页面里即可:
class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('垂直轮播示例')), body: const VerticalCarouselSlider(), ); } }
自定义提示
- 可以根据你的参考设计,修改轮播项的UI布局、样式
CarouselOptions里的参数(比如自动播放速度、是否循环、滑动灵敏度)都可以按需调整- 如果API需要授权,记得在请求里加上对应的header
内容的提问来源于stack exchange,提问作者Pranav Ratusaria
相关产品推荐
相关产品推荐

