Flutter中WebView嵌入SizedBox报错,求解决方案
问题分析与解决方案
当然可以实现这个需求!你遇到的错误核心原因很明确:webview.launch()方法返回的是Future<void>(它是用来调用系统浏览器打开外部网页的),而SizedBox的child参数要求传入一个Widget类型的对象,两者类型不匹配,所以才会抛出这个错误。
你完全不需要用FutureBuilder来解决这个问题——因为问题根本不是需要等待异步结果渲染Widget,而是用错了WebView的实现方式。下面是正确的实现步骤:
步骤1:添加正确的WebView依赖
首先确保你在pubspec.yaml中引入官方的webview_flutter包(这是Flutter官方维护的WebView组件,用于在App内部渲染网页):
dependencies: flutter: sdk: flutter webview_flutter: ^4.0.0 # 建议使用最新稳定版本
步骤2:替换错误的WebView实现
先导入包:
import 'package:webview_flutter/webview_flutter.dart';
然后把你代码中错误的webview.launch()部分替换成内部WebView组件:
如果你使用的是webview_flutter 4.x+版本(最新版)
new SizedBox( height: 50.0, width: 600.0, child: WebViewWidget( controller: WebViewController() ..loadRequest(Uri.parse("你的目标URL")), // 替换成实际的网页地址 ), ),
如果你使用的是webview_flutter 3.x及以下版本
new SizedBox( height: 50.0, width: 600.0, child: WebView( initialUrl: "你的目标URL", // 替换成实际的网页地址 javascriptMode: JavascriptMode.unrestricted, // 按需开启JavaScript支持,可选 ), ),
为什么原来的方法不行?
webview.launch()是另一个工具包(比如url_launcher)里的方法,它的作用是唤起手机系统自带的浏览器打开网页,而不是在你的Flutter页面内部嵌入WebView。所以它的返回值是Future,表示异步打开浏览器的操作,而不是一个可以直接渲染的Widget。
修改后的完整代码片段参考
import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; class YourPage extends StatefulWidget { @override _YourPageState createState() => _YourPageState(); } class _YourPageState extends State<YourPage> { final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); void stop() { // 你的stop方法逻辑 } void play() { // 你的play方法逻辑 } void _showSnackBar() { _scaffoldKey.currentState?.showSnackBar(const SnackBar(content: Text("暂停"))); } void _showSnackBar2() { _scaffoldKey.currentState?.showSnackBar(const SnackBar(content: Text("播放"))); } @override Widget build(BuildContext context) { SystemChrome.setEnabledSystemUIOverlays([SystemUiOverlay.bottom]); return Scaffold( key: _scaffoldKey, floatingActionButton: Row( mainAxisSize: MainAxisSize.min, children: <Widget>[ GestureDetector( child: Image.network("http://modernworfare.altervista.org/pause.png", width: 80.0,), onTap: (){stop(); _showSnackBar();}, ), GestureDetector( child: Image.network("http://modernworfare.altervista.org/bg.png",width: 80.0,), onTap: (){play(); _showSnackBar2();}, ), ], ), backgroundColor: Colors.black, body: ListView( children: <Widget>[ Column( children: <Widget>[ Image.network("https://scontent-mxp1-1.xx.fbcdn.net/v/t1.0-9/16864236_1836092593321492_1828236030296093399_n.jpg?_nc_cat=0&oh=817190c0ef6ac6e3076582905997f3e9&oe=5B81BFF9"), const Divider(), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ Container( padding: const EdgeInsets.all(8.0), child: const Text(" WEBSITE ", style: TextStyle(color: Colors.white,)), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10.0), border: Border.all( width: 4.0, color: Colors.white, ), ), ), Container( padding: const EdgeInsets.all(8.0), child: const Text(" SOCIAL ", style: TextStyle(color: Colors.white,)), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10.0), border: Border.all( width: 4.0, color: Colors.white, ), ), ), Container( padding: const EdgeInsets.all(8.0), child: const Text(" SHOP ", style: TextStyle(color: Colors.white,)), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10.0), border: Border.all( width: 4.0, color: Colors.white, ), ), ), Container( padding: const EdgeInsets.all(8.0), child: const Text(" CONTACT ", style: TextStyle(color: Colors.white,)), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10.0), border: Border.all( width: 4.0, color: Colors.white, ), ), ) ], ), const Text("hi",style: TextStyle(color: Colors.white), ), SizedBox( height: 50.0, width: 600.0, child: WebViewWidget( controller: WebViewController() ..loadRequest(Uri.parse("你的目标URL")), ), ), ], ) ], ), ); } }
内容的提问来源于stack exchange,提问作者Alessandro Prece
相关产品推荐
相关产品推荐

