为Flutter的ListView.builder添加点击事件,跳转至PlayPage展示对应图片
实现ListView条目点击跳转并传递图片ID到PlayPage
核心实现步骤
- 给列表项添加点击交互:用
InkWell包裹每个条目,点击时触发页面跳转并携带图片ID - PlayPage接收参数并加载对应图片:通过构造函数接收ID,从
info.json匹配对应条目后展示图片 - 适配你的两列布局:保持奇偶索引分左右容器的逻辑,仅修改列表项的包裹组件
修改后的完整代码
主页面代码(含两列布局与点击逻辑)
import 'dart:convert'; import 'package:flutter/material.dart'; import 'PlayPage.dart'; class MainListPage extends StatefulWidget { const MainListPage({super.key}); @override State<MainListPage> createState() => _MainListPageState(); } class _MainListPageState extends State<MainListPage> { List<dynamic> infoItems = []; @override void initState() { super.initState(); _loadInfoData(); } // 加载info.json数据 Future<void> _loadInfoData() async { final jsonString = await DefaultAssetBundle.of(context).loadString('assets/info.json'); final data = json.decode(jsonString); setState(() => infoItems = data['items']); } @override Widget build(BuildContext context) { // 拆分奇偶索引条目 final oddItems = infoItems.where((item) => infoItems.indexOf(item) % 2 != 0).toList(); final evenItems = infoItems.where((item) => infoItems.indexOf(item) % 2 == 0).toList(); return Scaffold( appBar: AppBar(title: const Text('内容列表')), body: Row( children: [ // 左侧容器:奇数索引项 Expanded( child: ListView.builder( itemCount: oddItems.length, itemBuilder: (context, index) => _buildListItem(oddItems[index]), ), ), // 右侧容器:偶数索引项 Expanded( child: ListView.builder( itemCount: evenItems.length, itemBuilder: (context, index) => _buildListItem(evenItems[index]), ), ), ], ), ); } // 封装带点击事件的列表项 Widget _buildListItem(dynamic item) { return InkWell( splashColor: Colors.grey.withOpacity(0.3), // 点击波纹效果 onTap: () { // 跳转至PlayPage并传递图片ID Navigator.push( context, MaterialPageRoute( builder: (_) => PlayPage(imageId: item['id']), ), ); }, child: Container( margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), child: Image.network(item['imageUrl'], fit: BoxFit.cover), ), ); } }
PlayPage.dart代码(接收ID并展示对应图片)
import 'dart:convert'; import 'package:flutter/material.dart'; class PlayPage extends StatefulWidget { final String imageId; const PlayPage({super.key, required this.imageId}); @override State<PlayPage> createState() => _PlayPageState(); } class _PlayPageState extends State<PlayPage> { dynamic targetItem; @override void initState() { super.initState(); _getTargetItem(); } // 根据ID从info.json获取对应条目 Future<void> _getTargetItem() async { final jsonString = await DefaultAssetBundle.of(context).loadString('assets/info.json'); final data = json.decode(jsonString); setState(() { targetItem = data['items'].firstWhere((item) => item['id'] == widget.imageId); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('播放页面')), body: targetItem == null ? const Center(child: CircularProgressIndicator()) : Container( width: double.infinity, height: MediaQuery.of(context).size.height * 0.5, // 封面区域占屏幕一半高度 child: Image.network(targetItem['imageUrl'], fit: BoxFit.contain), ), ); } }
注意事项
- 确保
info.json的结构为:{ "items": [ {"id": "1", "imageUrl": "https://example.com/image1.jpg"}, {"id": "2", "imageUrl": "https://example.com/image2.jpg"} ] } - 如果使用本地图片,将
Image.network替换为Image.asset,并修改图片路径 - 可添加错误处理逻辑(比如
firstWhere没找到匹配项时的处理),避免崩溃
内容的提问来源于stack exchange,提问作者mehrdad ghadermarzi
相关产品推荐
相关产品推荐

