Руководство по использованию плагина Flutter webview_flutter

Flutter

статус-кво

В настоящее время существует два основных подключаемых модуля,flutter_webview_pluginа такжеwebview_flutter.flutter_webview_pluginЭто сторонний плагин, и документация будет более полной.starТоже самое. Но есть две основные проблемы при использовании:

  • Не могу вызвать метод Flutter в JS
  • Невозможно перехватить H5 перед вводом URL

Так что в этой статье используется официальнаяwebview_flutter, в настоящее время все еще находится в предварительной версии, с нетерпением жду новых функций

Установить плагин

pubspec.yaml

dependenciesУвеличиватьwebview_flutter: ^0.3.13, используйте последнюю версию,

dependencies:
  webview_flutter: ^0.3.13

info.list

дорожка:ios/Runner/info.list, добавить конфигурацию:

<key>io.flutter.embedded_views_preview</key>
<string>YES</string>

<key>NSAppTransportSecurity</key>
<dict>
	<key>NSAllowsArbitraryLoads</key>
	<true/>
	<key>NSAllowsArbitraryLoadsInWebContent</key>
	<true/>
</dict>

использовать

Список параметров

имя параметра Типы По умолчанию иллюстрировать
initialUrl String ''
onWebViewCreated Function Вызывается при создании WebView
javascriptMode JavascriptMode JavascriptMode.disabled Режим выполнения JS не вызывается по умолчанию
javascriptChannels Set Используйте JavaScriptChannel JS для вызова Flutter
navigationDelegate Function запрос на перехват
onPageFinished Function вызов завершения загрузки страницы
gestureRecognizers Set жест

Сцены

Самый простой способ загрузить URL

WebView(
  initialUrl: "https://flutterchina.club/",
  //JS执行模式 是否允许JS执行
  javascriptMode: JavascriptMode.unrestricted
)

h5 вызывает флаттер -- JavascriptChannel

// 往h5 window 里面插入全局方法 Toaster
JavascriptChannel _toastJavascriptChannel(BuildContext context) {
  return JavascriptChannel(
    name: 'Toaster',
    onMessageReceived: (JavascriptMessage message) {
      print(message);
      Fluttertoast.showToast(
        msg: message.message
      );
    });
}

// 往 Webview 组件注册 javascriptChannels
new WebView(
  ...
  javascriptChannels: <JavascriptChannel>[ //javascriptChannels这个是api提供的互调的方法,
    _toastJavascriptChannel(context),
  ].toSet()
)

// js 调用
Toaster.postMessage('js call flutter success!!')

h5 вызывает флаттер -- navigationDelegate

new WebView(
  ...
  navigationDelegate: (NavigationRequest request) {
  // print('navigationDelegate: ${request.url}');
  if(request.url.indexOf('m=webview') > -1) {
    String _url = helper.addUrlParam(request.url.replaceAll('&m=webview', ''));
    Navigator.of(context).push(new MaterialPageRoute(builder: (_) {
      return Browser(
        title: ' ',
        url: _url
      );
    }));
    return NavigationDecision.prevent;
  }
)

флаттер колл h5

// 在页面加载完毕,修改 Webview 的标题
new WebView(
  ...
  onPageFinished: (url) {
    // 设置标题
    _controller.evaluateJavascript("document.title").then((result){
      print(result);
      setState(() {
        widget.title = result;
      });
    });
  },
)

полные компоненты

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:fluttertoast/fluttertoast.dart';

import '../helper/index.dart' as helper;

class Browser extends StatefulWidget {
  String url;
  String title;

  Browser({this.url, this.title});

  @override
  _BrowserState createState() => _BrowserState();
}

class _BrowserState extends State<Browser> {
  dynamic _controller;

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

  @override
  void dispose() {

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    JavascriptChannel _toastJavascriptChannel(BuildContext context) {
      return JavascriptChannel(
        name: 'Toaster',
        onMessageReceived: (JavascriptMessage message) {
          print(message);
          Fluttertoast.showToast(
            msg: message.message
          );
        });
    }

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Stack(
        children: <Widget>[
          new WebView(
            initialUrl: widget.url,
            javascriptMode: JavascriptMode.unrestricted,
            onWebViewCreated: (controller) {
              _controller = controller;
            },
            /**
             * 当 url 带有 'm=webview',则打开新的webview
             */
            navigationDelegate: (NavigationRequest request) {
              // print('navigationDelegate: ${request.url}');
              if(request.url.indexOf('m=webview') > -1) {
                String _url = helper.addUrlParam(request.url.replaceAll('&m=webview', ''));
                Navigator.of(context).push(new MaterialPageRoute(builder: (_) {
                  return Browser(
                    title: ' ',
                    url: _url
                  );
                }));
                return NavigationDecision.prevent;
              }

              return NavigationDecision.navigate;
            },
            onPageFinished: (url) {
              // 设置标题
              _controller.evaluateJavascript("document.title").then((result){
                print(result);
                setState(() {
                  widget.title = result;
                });
              });

              // var a = '123';
              // print(a+1);

              // 测试flutter 调用我页面的方法
              // _controller.evaluateJavascript("callJSFunc();").then((result){
              //   // print('callJSFunc has called: $result');
              // });
            },
            javascriptChannels: <JavascriptChannel>[ //javascriptChannels这个是api提供的互调的方法,
              _toastJavascriptChannel(context),
            ].toSet()
          )
        ],
      ),
    );
  }
}

todo

  • доступ к кордове
  • Получить сетевой статус устройства

Справочная статья