Flutter开发与Js的互相调用

就目前移动端的生态来说,实现混合开发,无论是Android端,Ios端,跟webview的交互,互相调用基本都都必须的,当然了,Flutter肯定也有与Js互相调用的方法,下面我们就来看看Flutter和Js互相调用吧

首先导入第三方框架

dependencies:
  flutter:
    sdk: flutter
  flutter_webview_plugin: ^0.3.5
  #  flutter_webview_plugin:
  #      path: ./../flutter_webview_plugin/
  #  flutter_webview_plugin:
  #      git:
  #      url: git://github.com/ChessLuo/flutter_webview_plugin.git

  webview_flutter: ^0.3.15+1 #flutter官方webview
  fluttertoast: ^3.0.4 #toast

下面看看使用示例




import 'dart:async';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:webview_flutter/webview_flutter.dart';
class FlutterWebView extends StatefulWidget {

  final String url="https://www.jianshu.com/u/69da9353384e";
  final String barTitle="我的简书";

//  const FlutterWebView({Key key, this.url, this.barTitle}) : super(key: key);

  @override
  State<StatefulWidget> createState() {
    return WebViewState();
  }
}

class WebViewState extends State<FlutterWebView> with AutomaticKeepAliveClientMixin {

  String _webUrl;

  @override
  void initState(){
    super.initState();
    _webUrl = Uri.decodeComponent(widget.url);

    print("web url == $_webUrl");

  }

  ///js与flutter交互
  JavascriptChannel _alertJavascriptChannel(BuildContext context) {
    return JavascriptChannel(
        name: 'invoke',//invoke要和网页协商一致
        onMessageReceived: (JavascriptMessage message) {
          print(message.message);

        });
  }

  ///组合脚本执行方法,将数据发送给js端(flutter与js交互)
  void _onExecJavascript(String url) async {
    _controller.future.then((controller) {
      controller.loadUrl(url);
    });
    //或者 evaluateJavascript('callJS("js方法")')
  }

  final Completer<WebViewController> _controller = Completer<WebViewController>();

  bool _loading = true; //等待加载框



  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title:Text(widget.barTitle,),
          centerTitle: true,
        ),
        body: SafeArea(//设置安全区域 ,不沉浸式
          top: true,
          child: Builder(builder: (BuildContext context) {
            return Stack(
              children: <Widget>[
                _showWebView(context),

                _loading
                    ? Center(child: CircularProgressIndicator(),)
                    :Container(),
              ],
            );


          }),
        )

    );
  }


  @override
  // TODO: implement wantKeepAlive
  bool get wantKeepAlive => true;

  ///初始化webview显示
  Widget _showWebView(BuildContext context) {
    return WebView(
      initialUrl: widget.url,///初始化url
      javascriptMode: JavascriptMode.unrestricted,///JS执行模式
      onWebViewCreated: (WebViewController webViewController) {///在WebView创建完成后调用,只会被调用一次
        //
        //
        _controller.complete(webViewController);
      },
      javascriptChannels: <JavascriptChannel>[///JS和Flutter通信的Channel;
        _alertJavascriptChannel(context),
      ].toSet(),
      navigationDelegate: (NavigationRequest request) {//路由委托(可以通过在此处拦截url实现JS调用Flutter部分);
        ///通过拦截url来实现js与flutter交互
        if (request.url.startsWith('js://webview')) {
          Fluttertoast.showToast(msg:'JS调用了Flutter By navigationDelegate');
//          print('blocking navigation to $request}');
          return NavigationDecision.prevent;///阻止路由替换,不能跳转,因为这是js交互给我们发送的消息
        }
        return NavigationDecision.navigate;///允许路由替换
      },
      onPageFinished: (String url) {///页面加载完成回调
        setState(() {
          _loading = false;
        });
        print('Page finished loading: $url');
      },

    );
  }
}

常规的使用上面都有了,朋友们可以运行下代码试试就OK啦,注释也写得很清楚了

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容