Flutter接入Firebase实现ListView点击跳转WebView的URL获取问题
问题根源
- 核心逻辑错误:你渲染列表的标题、图片、副标题时,都是直接从Firebase返回的当前文档数据
data中取值,但跳转WebView时错误尝试从widget传入的firBaseLists对象中取值,同时还写错了访问语法:把对象下标访问的[]写成了函数调用的(),自然无法拿到正确的URL。 - 冗余参数:
ListviewPage构造函数中定义的firBaseLists、webviewTitle、weburl三个参数没有实际作用,你已经通过StreamBuilder直接监听Firebase的listview集合获取了所有需要的字段数据。 - 小瑕疵:代码中使用了
CupertinoActivityIndicator但未导入Cupertino组件库,固定写死容器高度800在不同尺寸设备上会出现适配问题。
修复方案
仅需修改InkWell的onTap跳转逻辑,直接从当前文档的data中取url和title字段即可,修复后的核心代码如下:
// 仅展示修改后的onTap部分,其余代码保持不变 onTap: () { // 建议先加非空和格式校验,避免字段缺失或格式错误导致崩溃 if(data['url'] == null || !data['url'].toString().startsWith('http')){ ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('链接无效'))); return; } Navigator.push( context, MaterialPageRoute( builder: (context) => InAppWebViewx( // 直接从当前文档data中取标题和链接,不需要用widget的参数 title: data['titletext'].toString(), url: data['url'].toString(), ) ) ); },
完整可运行参考代码
import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; // 补全Cupertino组件导入 import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:watched_movie_list/Widget/webviewx.dart'; // 删掉无用的构造参数 class ListviewPage extends StatefulWidget { const ListviewPage({super.key}); @override _ListviewPageState createState() => _ListviewPageState(); } class _ListviewPageState extends State<ListviewPage> { @override Widget build(BuildContext context) { return StreamBuilder( stream: FirebaseFirestore.instance.collection('listview').snapshots(), builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { if (!snapshot.hasData) { return const Center( child: CupertinoActivityIndicator( radius: 20, ), ); } return Scaffold( appBar: AppBar( title: const Text( ' नवीनतम सूचनाएं', style: TextStyle(color: Colors.black), ), leading: const BackButton(color: Colors.black), backgroundColor: Colors.white, ), // 去掉固定高度,自适应屏幕 body: Container( color: const Color(0xfff5f5f5), child: ListView( padding: const EdgeInsets.symmetric(vertical: 8), children: snapshot.data!.docs.map((DocumentSnapshot document) { Map<String, dynamic> data = document.data()! as Map<String, dynamic>; return InkWell( onTap: () { if(data['url'] == null || !data['url'].toString().startsWith('http')){ ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('链接无效'))); return; } Navigator.push( context, MaterialPageRoute( builder: (context) => InAppWebViewx( title: data['titletext'].toString(), url: data['url'].toString(), ))); }, child: Container( height: 150, decoration: BoxDecoration( color: Colors.lightGreen, borderRadius: BorderRadius.circular(18)), margin: const EdgeInsets.only(right: 12, left: 12, bottom: 10), child: Row( children: [ Expanded( child: Container( padding: const EdgeInsets.only(top: 15, left: 20, right: 20), height: 150, child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Image.network( data['img'].toString(), height: 40, width: 40, errorBuilder: (context, error, stackTrace) { return const Icon(Icons.broken_image, size: 40, color: Colors.white,); }, ), Padding( padding: const EdgeInsets.only(top: 8.0), child: Text( data['titletext'].toString(), style: const TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Colors.white, ), ), ), Padding( padding: const EdgeInsets.only(top: 8.0), child: Text( data['subtitle'].toString(), maxLines: 2, style: const TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: Colors.white, ), ), ), ], ), ), ), ], ), ), ); }).toList(), ), ), ); }, ); } }
注意事项
- 确认Firebase控制台中
listview集合的每个文档都存在url字段,且字段值为合法的HTTP/HTTPS格式链接 - 代码中新增了图片加载错误占位、链接校验逻辑、适配优化,你可以根据自己的需求调整
内容的提问来源于stack exchange,提问作者AAKASH
相关产品推荐
相关产品推荐

