You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 07:35:16