如何在 Flutter 中重新加载 webview?

How to reload webview in Flutter?

在 Flutter 应用中,我想在按下应用栏上的刷新图标按钮时重新加载 Webview 页面。我正在使用官方 webview_flutter 并且不想使用 flutter_webview_plugin 因为我有一个侧抽屉。关于如何刷新 webview 页面有什么想法吗?

我尝试过使用 setState() 重建同一页面,但该应用程序并未自行重建。我也尝试过使用 navigator.push() 但这会指向全屏 webview 并覆盖抽屉和应用栏。

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',
    );
  }
}

首先你要获取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://whosebug.com",
    );
  }

  void reloadWebView() {
    _webViewController?.reload();
  }
}

您也可以使用

    icon: Icon(
                Icons.replay_outlined,
                color: Colors.amber,
              ),
              onPressed: () => controller.reload(),
              ),