1

我是 Flutter 的新手,我想在其他小部件之间放置一个 Web 视图,并且我正在使用 InAppWebView 颤振来执行此操作,但我想阻止用户在单击按钮时导航到其他页面在 web 视图中。我是否必须为 iOS 和 Android 编写一些本机代码来阻止导航?

谢谢

4

4 回答 4

2

类似的东西:

InAppWebView(
....
 shouldOverrideUrlLoading: (controller, navigationAction) async {
  final uri = navigationAction.request.url!;
  if(whitenAvigationHosts.contains(uri.host)){
    return NavigationActionPolicy.ALLOW;
  }
  return NavigationActionPolicy.CANCEL;
})
                
于 2021-07-09T23:03:34.050 回答
1

要禁用将用户导航到另一个页面,您可以使用onPageCommitVisible回调来确定用户单击重定向到另一个页面的 url,因此只需在其中调用 goBack

 InAppWebView(
        onPageCommitVisible: (con,uri){
          print("url ${uri.toString()}");
          con.goBack();
        },

      ),
于 2021-06-14T12:01:02.560 回答
0

禁用导航InAppWebView:-

我们在小部件中有onUpdateVisitedHistory属性。Inappwebview使用这个onUpdateVisitedHistory属性我们可以监听小部件中的 url 变化。Inappwebview所以禁用导航我们可以使用webcontroller.goback()方法。

小部件代码:

InAppWebView(
              key: webViewKey,
              onWebViewCreated: (controller) {
                webViewController = controller;
                _loadHtmlFromAssets();
              },
              onUpdateVisitedHistory: (controller, url, androidIsReload) {
                if (url!.host.contains("google.com")) {
                  webViewController?.goBack();
                  //You can do anything
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => const Screen1()),
                  );
                  //Prevent that url works
                  return;
                } else if (url.host.contains("yahoo.com")) {
                  //You can do anything
                  webViewController?.goBack();
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => const Screen3()),
                  );
                  //Prevent that url works
                  return;
                } else if (url.host.contains("duckduckgo.com")) {
                  //You can do anything
                  webViewController?.goBack();
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => const Screen2()),
                  );
                }
              })

在此处输入图像描述

这里我们跳过加载搜索引擎并跳转到其他小部件

注意:如果我们没有添加webcontroller.goback().it 将加载站点并移动到小部件。如果我们回按它将显示网页。

示例代码:

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  WebViewController? _controller;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  final GlobalKey webViewKey = GlobalKey();

  InAppWebViewController? webViewController;
  late PullToRefreshController pullToRefreshController;
  InAppWebViewGroupOptions options = InAppWebViewGroupOptions(
      crossPlatform: InAppWebViewOptions(
        useShouldOverrideUrlLoading: true,
        mediaPlaybackRequiresUserGesture: false,
      ),
      android: AndroidInAppWebViewOptions(
        useHybridComposition: true,
      ),
      ios: IOSInAppWebViewOptions(
        allowsInlineMediaPlayback: true,
      ));

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

    pullToRefreshController = PullToRefreshController(
      options: PullToRefreshOptions(
        color: Colors.blue,
      ),
      onRefresh: () async {
        if (Platform.isAndroid) {
          webViewController?.reload();
        } else if (Platform.isIOS) {
          webViewController?.loadUrl(
              urlRequest: URLRequest(url: await webViewController?.getUrl()));
        }
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            webViewController?.goBack();
          },
          child: Icon(Icons.arrow_back),
        ),
        appBar: AppBar(
          backgroundColor: Colors.black87,
          title: Text(widget.title),
        ),
        body: Center(
          child: InAppWebView(
              key: webViewKey,
              onWebViewCreated: (controller) {
                webViewController = controller;
                _loadHtmlFromAssets();
              },
              onUpdateVisitedHistory: (controller, url, androidIsReload) {
                if (url!.host.contains("google.com")) {
                  webViewController?.goBack();
                  //You can do anything
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => const Screen1()),
                  );
                  //Prevent that url works
                  return;
                } else if (url.host.contains("yahoo.com")) {
                  //You can do anything
                  webViewController?.goBack();
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => const Screen3()),
                  );
                  //Prevent that url works
                  return;
                } else if (url.host.contains("duckduckgo.com")) {
                  //You can do anything
                  webViewController?.goBack();
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => const Screen2()),
                  );
                }
              }),
        ));
  }

  _loadHtmlFromAssets() {
    var fileText =
        "<!DOCTYPE html> <html> <head> <title>HTML, CSS and JavaScript demo</title> <style> .rotate { transform: rotate(1700deg) ; } .rotate2 { transform: rotate(90deg) ; } .bg { background: url(https://picsum.photos/2000/1000?image=1069) center/cover; height: 50vh; width: 50vh; } body { margin:0; overflow:hidden; } </style> </head> "
        "<!-- Start your code here --> <ul> <li> <a href ='http://duckduckgo.com/' /><p> duckduckgo.com</a> </li>  <li> <a href='http://www.google.com'>google.com </a> </li>    <li> <a href='http://www.yahoo.com/'> yahoo.com </a> </li></ul> </html>";
    // return Uri.dataFromString(fileText,
    //         mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
    //     .toString();
    webViewController!.loadUrl(
        urlRequest: URLRequest(
            url: new Uri.dataFromString(fileText, mimeType: 'text/html')));

    // _controller?.loadUrl(Uri.dataFromString(fileText,
    //         mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
    //     .toString());
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class Screen1 extends StatelessWidget {
  const Screen1({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(
        child: Text("Screen 1 google.com"),
      ),
    );
  }
}

class Screen2 extends StatelessWidget {
  const Screen2({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: MaterialApp(
        home: Container(
          child: Text("Screen 2 yahoo.com"),
        ),
      ),
    );
  }
}

class Screen3 extends StatelessWidget {
  const Screen3({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(
        child: Text("Screen 3 duck.com"),
      ),
    );
  }
}

在小部件中禁用导航Webview

我们可以navigationDelegate用来监控 .url 中的 url 变化webviewNavigationDecision.prevent将阻止跳转到网站

WebView(
      // initialUrl: 'https://flutter.dev',
      onWebViewCreated: (WebViewController webViewController) {
        _controller = webViewController;
        _loadHtmlFromAssets();
      },
      navigationDelegate: (NavigationRequest request) {
        if (request.url.contains("google.com")) {
          //You can do anything
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => const Screen1()),
          );
          //Prevent that url works
          return NavigationDecision.prevent;
        } else if (request.url.contains("yahoo.com")) {
          //You can do anything
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => const Screen1()),
          );
          //Prevent that url works
          return NavigationDecision.prevent;
        } else if (request.url.contains("duckduckgo.com")) {
          //You can do anything
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => const Screen3()),
          );
          //Prevent that url works
          return NavigationDecision.prevent;
        }
        //Any other url works
        return NavigationDecision.navigate;
      },
    );
于 2022-02-13T13:38:18.367 回答
0

您可以通过如下导航委托属性阻止在 webview 中导航:

WebView(
        debuggingEnabled: true,
        initialUrl: _currentURL,
        onWebViewCreated: (controller) {
          _controller = controller;
          return _controller;
        },
        onPageFinished: (url) {
          if (url.contains(ConstUtils.course)) {
            updateProfile();
          }
        },
        navigationDelegate: (navigation) => NavigationDecision.prevent,
        onWebResourceError: (error) {
          NavigationUtils(context).popCurrentPage();
        },
        onPageStarted: (url) {
          
        },
        javascriptMode: JavascriptMode.unrestricted,
      ),
于 2021-01-04T05:28:49.747 回答