如何通过Navigator将CommentModel从commentItem Widget传至其他页面?
一、使用Navigator.push直接传递参数
1. 修改commentItem为可点击组件,触发跳转
给原有的评论项包裹GestureDetector,点击时将CommentModel传递到目标页面:
// 评论项组件,接收评论模型和上下文 Widget commentItem(CommentModel model, context,) => GestureDetector( // 点击跳转到帖子详情页 onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => PostDetailPage(commentModel: model), ), ); }, child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 用户头像 CircleAvatar( radius: 22, backgroundImage: NetworkImage('${model.image}'), ), SizedBox(width: 15), Expanded( child: Column( children: [ // 评论内容容器(根据主题切换背景色) Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: SocialCubit.get(context).iconChangeTheme ? Colors.white70 : Colors.grey[350], ), child: Padding( padding: const EdgeInsets.all(8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ // 用户名 Text( '${model.name}', style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: SocialCubit.get(context).iconChangeTheme ? Colors.black : Colors.black ), ), SizedBox(width: 7), // 评论时间 Text( '${model.dateTime}', style: TextStyle( fontSize: 11, color: SocialCubit.get(context).iconChangeTheme ? Colors.black : Colors.black ), ), ], ), // 文本内容不为空时显示间距 if(model.text != '') SizedBox(height: 5), // 评论文本 Text( '${model.text}', style: TextStyle( color: SocialCubit.get(context).iconChangeTheme ? Colors.black : Colors.black ), ), ], ), ), ), // 评论图片不为空时展示图片 if (model.commentImage != '') Padding( padding: const EdgeInsetsDirectional.only(top: 5), child: Container( height: 170, alignment: Alignment.topLeft, child: ClipRRect( borderRadius: BorderRadius.circular(10), child: Image( image: NetworkImage('${model.commentImage}'), alignment: Alignment.topLeft, ), ), ), ), ], ), ), ], ), ], ), );
2. 目标页面接收并展示参数
创建详情页,通过构造函数接收CommentModel并渲染内容:
class PostDetailPage extends StatelessWidget { final CommentModel commentModel; // 构造函数接收传递的评论模型 const PostDetailPage({Key? key, required this.commentModel}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('帖子详情')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ CircleAvatar( radius: 22, backgroundImage: NetworkImage(commentModel.image), ), SizedBox(height: 10), Text(commentModel.name, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), SizedBox(height: 5), Text(commentModel.dateTime, style: TextStyle(fontSize: 12, color: Colors.grey)), SizedBox(height: 15), Text(commentModel.text), // 展示评论图片(如果存在) if(commentModel.commentImage.isNotEmpty) Padding( padding: const EdgeInsets.only(top: 10), child: ClipRRect( borderRadius: BorderRadius.circular(10), child: Image.network(commentModel.commentImage, height: 200), ), ), ], ), ), ); } }
二、使用Navigator.pushNamed传递参数(命名路由)
1. 配置命名路由
在MaterialApp中注册路由:
MaterialApp( initialRoute: '/', routes: { '/': (context) => HomePage(), // 首页 '/postDetail': (context) => PostDetailPage(), // 帖子详情页路由 }, );
2. 修改commentItem的跳转逻辑
Widget commentItem(CommentModel model, context,) => GestureDetector( onTap: () { Navigator.pushNamed( context, '/postDetail', arguments: model, // 传递评论模型参数 ); }, child: Column( // 原评论项内容保持不变 ), );
3. 目标页面获取参数
修改详情页,通过ModalRoute获取传递的参数:
class PostDetailPage extends StatelessWidget { const PostDetailPage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { // 从路由参数中获取评论模型 final CommentModel commentModel = ModalRoute.of(context)!.settings.arguments as CommentModel; return Scaffold( appBar: AppBar(title: Text('帖子详情')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 渲染内容和之前一致 CircleAvatar( radius: 22, backgroundImage: NetworkImage(commentModel.image), ), SizedBox(height: 10), Text(commentModel.name, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), SizedBox(height: 5), Text(commentModel.dateTime, style: TextStyle(fontSize: 12, color: Colors.grey)), SizedBox(height: 15), Text(commentModel.text), if(commentModel.commentImage.isNotEmpty) Padding( padding: const EdgeInsets.only(top: 10), child: ClipRRect( borderRadius: BorderRadius.circular(10), child: Image.network(commentModel.commentImage, height: 200), ), ), ], ), ), ); } }
三、实现不同页面展示对应内容
个人资料页:仅展示当前用户的帖子
通过过滤数据实现:
class ProfilePage extends StatelessWidget { final String currentUserId; // 当前登录用户ID const ProfilePage({Key? key, required this.currentUserId}) : super(key: key); @override Widget build(BuildContext context) { // 过滤出当前用户发布的帖子 final userComments = SocialCubit.get(context).comments.where((comment) => comment.userId == currentUserId).toList(); return Scaffold( appBar: AppBar(title: Text('我的帖子')), body: ListView.separated( padding: EdgeInsets.all(16), itemBuilder: (context, index) => commentItem(userComments[index], context), separatorBuilder: (context, index) => SizedBox(height: 20), itemCount: userComments.length, ), ); } }
首页:展示所有帖子
直接使用原有的列表代码即可:
ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemBuilder: (context, index) => commentItem(SocialCubit.get(context).comments[index], context), separatorBuilder: (context, index) => SizedBox(height: 20), itemCount: SocialCubit.get(context).comments.length, ),
内容的提问来源于stack exchange,提问作者hazem saad
相关产品推荐
相关产品推荐

