Flutter Webview多层嵌套 处理回退历史

在FlutterApp开发中,当使用WebView打开网页并点击链接跳转后,按系统返回键应返回之前的网页而不是Native页面。通过WebViewController的canGoBack方法判断并使用goBack()可以实现预期的Webview历史回退,否则响应系统回退,确保导航行为正确。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在 App 开发中,我们总会遇到使用 WebView 的情况, 比如 我们打开了 网页A,然后点击 A 中的链接跳转到 B。如果这个时候,我们按一下系统的返回键,预期的应该是 返回A,而不是推到一个 Native 页面。

但事实就是,如果你没有经过特殊处理,那么很有可能就不是预期的效果(B –> A)。不过还在我们只需要简单修改代码,就能解决。

再次明确一下,我们的预期

  • 如果 webview 有可以回退的历史,当系统返回按键点击后,进行 webview 历史回退
  • 否则执行 系统回退,返回上一个 native界面

用到的核心代码

WebViewController? _webviewController;




WillPopScope(
  onWillPop: () => _exitApp(context),
  child: xxx,   
}



Future<bool> _exitApp(BuildContext context) async {
 if (await _webviewController!.canGoBack()) {
   print("onwill goback");
   _webviewController!.goBack();
   return Future.value(false);
 } else {
   debugPrint("_exit will not go back");
   return Future.value(true);
 }
}
  • WebViewController 实例 controllerGlobal 是用来判断检测并执行 webview 历史回退。
  • 使用 WillPopScope 用来监听 系统的返回键调用,并进行执行系统返回还是 回退 WebView 历史
  • 这里利用 controllerGlobal!.canGoBack 来判断是否可以回退 webview 历史
  • 如果需要执行 webview 回退历史,调用 controllerGlobal!.goBack(), 否则响应系统回退

完整的实例代码

class WebViewExample extends StatefulWidget {
  @override
  _WebViewExampleState createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  late WebViewController _webviewController;

  Future<bool> _exitApp(BuildContext context) async {
    if (await _webviewController.canGoBack()) {
      // 查看  history 有没有可以返回的  如果有  则返回 history
      print("onwill goback");
      print("进来里唯一返回的");
      _webviewController.goBack(); // history 返回
      return Future.value(false);
    } else {
      print("这里history没有返回的");
      debugPrint("_exit will not go back");
      return Future.value(true);
    }
  }

  @override
  void initState() {
    super.initState();
    _webviewController = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      
      ..setNavigationDelegate(
        NavigationDelegate(
          onProgress: (int progress) {
            // Update loading bar.
          },
          onPageStarted: (String url) {},
          onPageFinished: (String url) {
            // setState(() {
            //   showLoading = false;
            // });
          },
          onWebResourceError: (WebResourceError error) {
            print("打印失败");
            print(error);
          },
          onNavigationRequest: (NavigationRequest request) {
          
            
            return NavigationDecision.navigate;
          },
        ),
      )
      ..loadRequest(Uri.parse(
          "http://droidyue.com"));
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () => _exitApp(context),
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Flutter WebView example'),
          // This drop down menu demonstrates that Flutter widgets can be shown over the web view.
        ),
        // We're using a Builder here so we have a context that is below the Scaffold
        // to allow calling Scaffold.of(context) so we can show a snackbar.
        body: Builder(builder: (BuildContext context) {
          return WebViewWidget(
            // initialUrl: 'http://droidyue.com',
            // javascriptMode: JavascriptMode.unrestricted,
            // onWebViewCreated: (WebViewController webViewController) {
            //   _webviewController = webViewController;
            // },
            controller: _webviewController,
          );
        }),
      ),
    );
  }
}

转载:Flutter webview 处理回退历史 - 技术小黑屋

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值