Flutter如何将List中的电影数据从列表页传递到详情页?
第一步:修改详情页MovieScreen接收Movie参数
首先给MovieScreen添加必传的Movie类型参数,移除原来写死的photo变量,后续直接通过传入的movie对象获取所有关联数据:
class MovieScreen extends StatefulWidget { // 添加必传的movie参数 final Movie movie; const MovieScreen({super.key, required this.movie}); @override _MovieScreenState createState() => _MovieScreenState(); } class _MovieScreenState extends State<MovieScreen> { @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: ListView( children: [ Stack( children: [ Container( transform: Matrix4.translationValues(0, -50, 0), width: double.infinity, child: Hero( // 用movie的唯一资源地址作为tag,保证和首页动画联动 tag: widget.movie.imgUrl, child: ClipShadowPath( clipper: CircularClipper(), shadow: const Shadow(blurRadius: 20), child: Image( height: 400, // 替换为传入的电影封面,也可以按需取screenshots列表里的截图 image: NetworkImage(widget.movie.imgUrl), fit: BoxFit.cover, ), ), ), ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ IconButton( padding: const EdgeInsets.only(left: 20), onPressed: () => Navigator.pop(context), icon: const Icon(Icons.arrow_back), iconSize: 30, ), IconButton( padding: const EdgeInsets.only(right: 20), onPressed: () {}, icon: const Icon(Icons.favorite_outline), iconSize: 30, color: Colors.red, ), ], ), // 后续可直接通过widget.movie.属性名拓展其他信息展示 // 示例: // Padding( // padding: EdgeInsets.only(top: 380, left: 20), // child: Text( // widget.movie.title, // style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold), // ), // ) ], ), ], ), ); } }
第二步:修改首页轮播逻辑,绑定对应电影数据
原代码把GestureDetector套在整个轮播组件外层,无法区分点击的是哪个电影,我们给每个轮播子项单独绑定点击事件,直接拿到对应电影对象:
class MainHome extends StatefulWidget { @override _MainHomeState createState() => _MainHomeState(); } class _MainHomeState extends State<MainHome> { @override Widget build(BuildContext context) { return Scaffold( body: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Navbar(), Container( width: MediaQuery.of(context).size.width - 60, child: ListView( children: <Widget>[ const SizedBox(height: 50), HeadMenu(), const SizedBox(height: 20), // 移除原外层的GestureDetector,改为子项单独绑定 CarouselSlider( items: movies .map((e) => GestureDetector( onTap: () => Navigator.push( context, MaterialPageRoute( // 直接把当前点击的电影对象传给详情页 builder: (_) => MovieScreen(movie: e), ), ), child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), image: DecorationImage( image: NetworkImage(e.imgUrl), fit: BoxFit.fitHeight), ), // 首页也添加对应tag的Hero,实现跳转联动动画 child: Hero(tag: e.imgUrl, child: const SizedBox.expand()), ), )) .toList(), options: CarouselOptions( height: 450, viewportFraction: 0.65, autoPlay: true, autoPlayInterval: const Duration(seconds: 3), autoPlayAnimationDuration: const Duration(milliseconds: 800), autoPlayCurve: Curves.fastOutSlowIn, enlargeCenterPage: true, ), ), ], ), ), ], ), ); } }
补充说明
后续需要在详情页展示其他电影信息时,直接通过widget.movie.属性名调用即可,比如widget.movie.description获取电影简介、widget.movie.screenshots获取所有截图列表,无需额外做数据查询。
内容的提问来源于stack exchange,提问作者ArQczeg14
相关产品推荐
相关产品推荐

