如何在 Flutter 中重新加载 webview?
Posted
技术标签:
【中文标题】如何在 Flutter 中重新加载 webview?【英文标题】:How to reload webview in Flutter? 【发布时间】:2019-12-04 13:13:27 【问题描述】:在 Flutter 应用程序中,当我按下应用程序栏上的刷新图标按钮时,我想重新加载 Webview 页面。我正在使用官方的 webview_flutter 并且不想使用 flutter_webview_plugin,因为我有一个侧抽屉。关于如何刷新网页视图页面的任何想法?
我尝试使用 setState() 重建同一页面,但应用程序不会自行重建。我也尝试过使用 navigator.push() 但这会指向全屏 web 视图并覆盖抽屉和应用栏。
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text(widget.drawerItems[_selectedDrawerIndex].title, style: TextStyle(
shadows: <Shadow>[
Shadow(
offset: Offset(1.0, 1.0),
blurRadius: 10.0,
color: Color(0xff185B1E),
),
],
color: Colors.white,
),
),
backgroundColor: Color(0xff9ABDFF),
iconTheme: IconThemeData(color: Colors.white),
actions: <Widget>[
IconButton(
icon: Icon(Icons.refresh),
color: Colors.white,
onPressed: ()
setState(()
_selectedDrawerIndex = 3;
//refresh webview here
);
,
),
]
body: _getDrawerItemWidget(_selectedDrawerIndex),
//_getDrawerItemWidget refers to a webview page
),
下面是我的 webview 小部件:
class Web1 extends StatelessWidget
@override
Widget build(BuildContext ctxt)
return WebView(
key: UniqueKey(),
javascriptMode: JavascriptMode.unrestricted,
initialUrl: 'http://www.google.com',
);
【问题讨论】:
【参考方案1】:首先你必须获取 WebViewController 并存储它。为此,将 WebView 移动到 StatefulWidget(我们将其命名为 WebViewContainer)并将 onWebViewCreated
回调传递给它。
现在您可以通过调用webViewController.reload()
方法重新加载WebView。
第二件事是从外部触发重新加载。有多种方法可以做到这一点,我认为最简单的选择是使用 GlobalKey。所以你需要创建一个final webViewKey = GlobalKey<WebViewContainerState>()
。将 webViewKey
传递给 WebViewContainer 构造函数。之后你就可以通过webViewKey.currentState
访问WebViewContainerState了。
示例代码:
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
final webViewKey = GlobalKey<WebViewContainerState>();
class WebViewPage extends StatefulWidget
@override
WebViewPageState createState() => WebViewPageState();
class WebViewPageState extends State<WebViewPage>
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text("WebView example"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.refresh),
onPressed: ()
// using currentState with question mark to ensure it's not null
webViewKey.currentState?.reloadWebView();
,
)
],
),
body: WebViewContainer(key: webViewKey),
);
class WebViewContainer extends StatefulWidget
WebViewContainer(Key key) : super(key: key);
@override
WebViewContainerState createState() => WebViewContainerState();
class WebViewContainerState extends State<WebViewContainer>
WebViewController _webViewController;
@override
Widget build(BuildContext context)
return WebView(
onWebViewCreated: (controller)
_webViewController = controller;
,
initialUrl: "https://***.com",
);
void reloadWebView()
_webViewController?.reload();
【讨论】:
按下按钮“setState(() );”【参考方案2】:你也可以使用
icon: Icon(
Icons.replay_outlined,
color: Colors.amber,
),
onPressed: () => controller.reload(),
),
【讨论】:
【参考方案3】:您可以尝试使用重新渲染所有小部件。在我的例子中,小部件是 HomePage。使用Naviagator.push 方法可以刷新所有小部件。
floatingActionButton: FloatingActionButton(
child: Icon(Icons.refresh),
backgroundColor: Colors.blueAccent,
onPressed: ()
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomePage()),
);
),
【讨论】:
以上是关于如何在 Flutter 中重新加载 webview?的主要内容,如果未能解决你的问题,请参考以下文章
使用flutter_webview_plugin加载页面后如何在WebView中执行JavaScript代码