Flutter WebViewController报错:Missing scheme in uri: null 问题求解
解决WebView加载URL时的"Missing scheme in uri: null"错误
1. 修复数据映射的笔误
问题根源是news_card.dart中数据映射时的键名错误:你在documents.map里写了'link"': e['link'],,键名多了一个多余的双引号,导致后续thisItem['link']无法取到正确值,传递给NewsDetails的link参数为null。
修改后的代码片段:
List<Map> items = documents .map((e) => { 'id': e.id, 'newsTitle': e['newsTitle'], 'publisherName': e['publisherName'], 'imageUrl': e['imageUrl'], 'publisherImageUrl': e['publisherImageUrl'], 'publisherRectangleUrl': e['publisherRectangleUrl'], 'updated': e['updated'], 'link': e['link'], // 去掉键名末尾的多余双引号 }) .toList();
2. 增加空值与URL合法性校验
即使修复笔误,也要处理Firestore中link字段为空或格式不规范的情况,避免重复报错:
跳转前校验链接有效性
在news_card.dart的onTap事件中先判断链接是否有效:
onTap: () { final String? targetLink = thisItem['link']; if (targetLink != null && targetLink.isNotEmpty) { Navigator.push( context, MaterialPageRoute( builder: (context) => NewsDetails( link: targetLink, image: '${thisItem['publisherImageUrl']}', title: '${thisItem['publisherName']}', ))); } else { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('该新闻链接无效')), ); } },
加载前补全URL协议头
在news_details.dart的initState中,确保URL包含http://或https://协议头:
@override void initState() { super.initState(); String validUrl = widget.link; // 自动补全缺失的协议头 if (!validUrl.startsWith('http://') && !validUrl.startsWith('https://')) { validUrl = 'https://$validUrl'; } _controller = WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) ..setBackgroundColor(const Color(0x00000000)) ..setNavigationDelegate( NavigationDelegate( onProgress: (int progress) {}, onPageStarted: (String url) {}, onPageFinished: (String url) {}, onWebResourceError: (WebResourceError error) {}, onNavigationRequest: (NavigationRequest request) { if (request.url.startsWith('https://www.youtube.com/')) { return NavigationDecision.prevent; } return NavigationDecision.navigate; }, ), ) ..loadRequest(Uri.parse(validUrl)); }
3. 简化State类参数传递
NewsDetailsState无需单独存储参数,直接使用widget对象的属性即可,避免参数顺序错误:
class _NewsDetailsState extends State<NewsDetails> { WebViewController? _controller; @override void initState() { super.initState(); String validUrl = widget.link; if (!validUrl.startsWith('http://') && !validUrl.startsWith('https://')) { validUrl = 'https://$validUrl'; } _controller = WebViewController() // ... 其他配置 ..loadRequest(Uri.parse(validUrl)); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( elevation: 1, backgroundColor: Colors.white, leading: GestureDetector( onTap: () => Navigator.pop(context), child: const Icon(Icons.arrow_back, color: Colors.black), ), title: Container( width: double.maxFinite, child: Row( children: <Widget>[ Container( child: Image.network( widget.image, fit: BoxFit.contain, height: 32, ), ), Container( padding: const EdgeInsets.only(left: 5), child: Text( widget.title, style: const TextStyle(color: Colors.black), ), ) ], ), ), ), body: WebViewWidget(controller: _controller!), ); } }
内容的提问来源于stack exchange,提问作者user21183878
相关产品推荐
相关产品推荐

