如何检测 webview url 何时发生变化?

How to detect when webview url changes in flutter?

我一直在寻找 flutter 中的 webview 插件,它可以检测 url 何时更改,但没有找到匹配项?我试图检测 url 更改的原因是因为我想在更改时将 bool 变量更改为 true,这将更改应用栏的颜色,这可能吗?有没有 simple/easy那里的例子可以实现我正在寻找的东西?提前感谢您的帮助!

您可以使用 StreamSubscription.

  StreamSubscription<String> _onStateChanged;
  final flutterWebviewPlugin = new FlutterWebviewPlugin();

      @override
      void initState() {
        super.initState();
    
        _onStateChanged =
            flutterWebviewPlugin.onUrlChanged.listen((String state) async {
          if (state.startsWith('your_url')) {
                // do whatever you want 
           }
        });
      }

对于 flutter webview 我使用下面的代码

 body: WebView(
          onPageFinished: (url){
            if (url.toLowerCase().contains("google.com") && url.toLowerCase().contains("status")) {
              if (url.toLowerCase().contains("notok")) {

                Fluttertoast.showToast(msg: "not successfull");
               
              } else if (url.toLowerCase().contains("ok")) {
               
                Fluttertoast.showToast(msg: "successful!");

              }
            }
          },
          javascriptMode: JavascriptMode.unrestricted,
          initialUrl: widget.paymentUrl,
        ));

您可以使用 navigationDelegate:

WebView(
    initialUrl: yourInitialUrl,
    javascriptMode: JavascriptMode.unrestricted,
    onWebViewCreated: (WebViewController webViewController) {
      _controller.complete(webViewController);
    },
    navigationDelegate: (NavigationRequest request) {
      if(request.url.startsWith(urlSearched)) {

        //You can do anything

        //Prevent that url works
        return NavigationDecision.prevent;
      }
      //Any other url works
      return NavigationDecision.navigate;
    },
  )

在 Webview 中你有可选的 navigationDelegate 参数

WebView(
      // initialUrl: 'https://flutter.dev',
      onWebViewCreated: (WebViewController webViewController) {
        _controller = webViewController;
        _loadHtmlFromAssets();
      },
      navigationDelegate: (NavigationRequest request) {
        setState(() {
      widget.appBarcolor = Colors.black87;
    });
        //Any other URL works
        return NavigationDecision.navigate;
      },
    );
  }

示例:

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

  final String title;
  Color appBarcolor = Colors.blue;

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

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

  WebViewController? _controller;

  @override
  void initState() {
    super.initState();
    // Enable virtual display.
    if (Platform.isAndroid) WebView.platform = AndroidWebView();
  }

  void _incrementCounter() {
    _controller!.goBack();
    setState(() {
      widget.appBarcolor = Colors.blue;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: widget.appBarcolor,
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: controller(),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.arrow_back),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

  _loadHtmlFromAssets() async {
    // String fileText = await rootBundle.loadString('assets/help.html');
    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>";
    _controller?.loadUrl(Uri.dataFromString(fileText,
            mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
        .toString());
  }

  WebView controller() {
    return WebView(
      // initialUrl: 'https://flutter.dev',
      onWebViewCreated: (WebViewController webViewController) {
        _controller = webViewController;
        _loadHtmlFromAssets();
      },
      navigationDelegate: (NavigationRequest request) {
        setState(() {
          widget.appBarcolor = Colors.black87;
        });

        //Any other url works
        return NavigationDecision.navigate;
      },
    );
  }
}

同时调试导航请求值: