如何在Flutter中打开多个WebView?

6
我有一个简单的Flutter WebView应用程序来显示我的网站。问题是,在我的网站上,我有两个功能可以打开新浏览器窗口。
例如,其中之一是Facebook登录功能,当用户点击使用Facebook登录时,它会加载Facebook登录API页面,当登录完成后,它会告诉用户返回到另一个页面,但由于我在WebView中,无法返回到另一个页面。
是否有一种方式可以在Flutter中打开2个WebViews以加载不同的页面?如果没有,这个问题还有其他可能的解决方案吗?
1个回答

2

webview_flutter插件没有提供管理和拦截新窗口将要打开的事件,例如当您点击带有target="_blank"的链接按钮或JavaScript端调用window.open()时。

因此,您可以使用我的插件flutter_inappwebview,它是一个Flutter插件,允许您添加内联WebViews或打开应用内浏览器窗口,并具有大量事件、方法和选项来控制WebViews。

它实现了onCreateWindow事件,这是当WebView请求主机应用程序创建新窗口时触发的事件,例如尝试使用target="_blank"打开链接或JavaScript端调用window.open()时。

以下是一个示例,其中我加载了一个简单的初始HTML(仅为了示例),其中包含一个按钮<button id="login-button">LOGIN</button>,当单击该按钮时,它会在AlertDialog中打开一个新的WebView。通过这个新的WebView,您可以通过onLoadStop事件或使用shouldOverrideUrlLoading事件来监听URL更改,或者在用户登录后检查并获取特定的cookie。您可以在这个新的WebView中放置任何逻辑。

以下是代码示例:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(initialRoute: '/', routes: {
      '/': (context) => InAppWebViewExampleScreen(),
    });
  }
}

class InAppWebViewExampleScreen extends StatefulWidget {
  @override
  _InAppWebViewExampleScreenState createState() =>
      new _InAppWebViewExampleScreenState();
}

class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
  InAppWebViewController _webViewController;
  CookieManager _cookieManager = CookieManager.instance();

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("InAppWebView")),
        body: Container(
            child: Column(children: <Widget>[
          Expanded(
              child: InAppWebView(
            initialData: InAppWebViewInitialData(data: """
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>InAppWebViewInitialDataTest</title>
    </head>
    <body>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi dolor diam, interdum vitae pellentesque sit amet, scelerisque at magna. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
        <p>Nullam vitae fringilla mauris, eu efficitur erat. Nulla aliquam ligula nec leo ornare varius. Curabitur ornare ultrices convallis.</p>
        <button id="login-button">LOGIN</button>
        <script>
          document.querySelector('#login-button').addEventListener('click', function (event) {
            window.open('https://github.com/', '_blank');
          });
        </script>
    </body>
</html>
                    """),
            initialHeaders: {},
            initialOptions: InAppWebViewGroupOptions(
                crossPlatform: InAppWebViewOptions(
                  debuggingEnabled: true,
                ),
                android:
                    AndroidInAppWebViewOptions(supportMultipleWindows: true)),
            onWebViewCreated: (InAppWebViewController controller) {
              _webViewController = controller;
            },
            onLoadStart: (InAppWebViewController controller, String url) {

            },
            onLoadStop: (InAppWebViewController controller, String url) {

            },
            onCreateWindow: (controller, onCreateWindowRequest) {
              showDialog(
                context: context,
                builder: (context) {
                  return AlertDialog(
                      content: Container(
                          width: 700,
                          child: Column(children: <Widget>[
                            Expanded(
                                child: InAppWebView(
                              initialUrl: onCreateWindowRequest.url,
                              initialOptions: InAppWebViewGroupOptions(
                                  crossPlatform: InAppWebViewOptions(
                                      debuggingEnabled: true,
                                      useShouldOverrideUrlLoading: true)),
                              onLoadStart: (InAppWebViewController controller,
                                  String url) {},
                              onLoadStop: (controller, url) async {
                                print(url);
                                if (url == "myURL") {
                                  Navigator.pop(context);
                                  return;
                                }

                                var loggedInCookie = await _cookieManager.getCookie(url: url, name: "logged_in");
                                if (loggedInCookie.value == "yes") {
                                  Navigator.pop(context);
                                  return;
                                }
                              },
                              shouldOverrideUrlLoading: (controller,
                                  shouldOverrideUrlLoadingRequest) async {
                                print(shouldOverrideUrlLoadingRequest.url);
                                if (shouldOverrideUrlLoadingRequest.url == "myURL") {
                                  Navigator.pop(context);
                                }
                                return ShouldOverrideUrlLoadingAction.ALLOW;
                              },
                            ))
                          ])));
                },
              );
            },
          ))
        ])));
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接