简体   繁体   English

有没有办法在 Flutter WebView 中导入外部脚本

[英]Is there a way to import external scripts in Flutter WebView

I'm trying to load an external script into Flutter WebView, but it doesn't seem to work.我正在尝试将外部脚本加载到 Flutter WebView 中,但它似乎不起作用。 It's about tinyMCE in particular.特别是关于tinyMCE。 So the intention is to open a rich text editor in an AlertDialog with WebView inside.所以目的是在一个带有 WebView 的 AlertDialog 中打开一个富文本编辑器。 Is that possible?那可能吗?

The following is my html:以下是我的html:

<html>
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/5.2.1/tinymce.min.js"></script>
</head>
<body>
<textarea id="test"></textarea>
<script>
  tinymce.init({
    selector: 'textarea#test',
    height: 500,
    menubar: false,
    plugins: [
      'advlist autolink lists link image charmap print preview anchor',
      'searchreplace visualblocks code fullscreen',
      'insertdatetime media table paste code help wordcount'
    ],
    toolbar: 'undo redo | formatselect | ' +
    'bold italic backcolor | alignleft aligncenter ' +
    'alignright alignjustify | bullist numlist outdent indent | ' +
    'removeformat | help',
  });
</script>
</body>
</html>

And that's my widget:这就是我的小部件:

import 'dart:convert';

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

class RichTextEditor extends StatefulWidget {
  final String html;

  const RichTextEditor({
    this.html: '',
  });

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

class RichTextEditorState extends State<RichTextEditor> {
  WebViewController _webViewController;

  @override
  Widget build(BuildContext context) {
    final String source = Uri.dataFromString(
      widget.html,
      mimeType: 'text/html',
      encoding: Encoding.getByName('utf-8'),
    ).toString();

    return Container(
      child: Material(
        child: Column(
          children: <Widget>[
            Row(
              children: <Widget>[
                IconButton(
                  icon: Icon(Icons.close),
                  onPressed: () => Navigator.of(context).pop(),
                ),
              ],
              mainAxisAlignment: MainAxisAlignment.end,
            ),
            Expanded(
              child: WebView(
                initialUrl: source,
                javascriptMode: JavascriptMode.unrestricted,
                onWebViewCreated: (WebViewController controller) {
                  _webViewController = controller;
                  _webViewController.loadUrl(source);
                },
              ),
            ),
          ],
        ),
      ),
      padding: EdgeInsets.all(10.0),
    );
  }

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

I get the following logs in the console:我在控制台中得到以下日志:

D/cr_Ime  (30910): [InputMethodManagerWrapper.java:30] Constructor
W/cr_AwContents(30910): onDetachedFromWindow called when already detached. Ignoring
D/cr_Ime  (30910): [InputMethodManagerWrapper.java:59] isActive: false
I/cr_Ime  (30910): ImeThread is not enabled.
D/EGL_emulation(30910): eglMakeCurrent: 0x8a0f4ca0: ver 2 0 (tinfo 0x8976d190)
W/cr_BindingManager(30910): Cannot call determinedVisibility() - never saw a connection for the pid: 30910
D/cr_Ime  (30910): [InputMethodManagerWrapper.java:59] isActive: true
D/cr_Ime  (30910): [InputMethodManagerWrapper.java:68] hideSoftInputFromWindow
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
D/EGL_emulation(30910): eglMakeCurrent: 0xb1e05240: ver 2 0 (tinfo 0xb1e03310)
W/cr_BindingManager(30910): Cannot call determinedVisibility() - never saw a connection for the pid: 30910
D/cr_Ime  (30910): [InputMethodManagerWrapper.java:59] isActive: true
D/cr_Ime  (30910): [InputMethodManagerWrapper.java:68] hideSoftInputFromWindow
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
I/art     (30910): Background sticky concurrent mark sweep GC freed 12(424B) AllocSpace objects, 0(0B) LOS objects, 0% free, 22MB/22MB, paused 10.801ms total 19.097ms
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
I/chromium(30910): [INFO:CONSOLE(9)] "Failed to initialize the editor as the document is not in standards mode. TinyMCE requires standards mode.", source: https://cdnjs.cloudflare.com/ajax/libs/tinymce/5.2.1/tinymce.min.js (9)
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread
W/art     (30910): Attempt to remove non-JNI local reference, dumping thread

Any help would be much appreciated.任何帮助将非常感激。 Thanks!谢谢!

To make TinyMCE work, you need to add also <!DOCTYPE html> at the start of your HTML (see https://community.tiny.cloud/communityQuestion?id=9064N000000MvpyQAC ).要使TinyMCE工作,您还需要在<!DOCTYPE html>的开头添加<!DOCTYPE html> (请参阅https://community.tiny.cloud/communityQuestion?id=9064N000000MvpyQAC )。

You can also try my plugin flutter_inappwebview if it doesn't work with webview_flutter .如果我的插件flutter_inappwebview不适用于webview_flutter您也可以尝试它。 It's a Flutter plugin that allows you to add inline WebViews or open an in-app browser window and has a lot of events, methods, and options to control WebViews.它是一个 Flutter 插件,允许您添加内联 WebView 或打开应用程序内浏览器窗口,并且有很多事件、方法和选项来控制 WebView。

Here is an example using initialData: InAppWebViewInitialData() attribute to inject an initial HTML string inside the WebView:下面是一个使用initialData: InAppWebViewInitialData()属性在 WebView 中注入初始 HTML 字符串的示例:

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

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

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

class _MyAppState extends State<MyApp> {
  InAppWebViewController webView;

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('InAppWebView Example'),
        ),
        body: Container(
            child: Column(children: <Widget>[
              Expanded(
                  child: InAppWebView(
                    initialData: InAppWebViewInitialData(data: """
<!DOCTYPE html>
<html>
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/5.2.1/tinymce.min.js"></script>
</head>
<body>
<textarea id="test"></textarea>
<script>
  tinymce.init({
    selector: 'textarea#test',
    height: 500,
    menubar: false,
    plugins: [
      'advlist autolink lists link image charmap print preview anchor',
      'searchreplace visualblocks code fullscreen',
      'insertdatetime media table paste code help wordcount'
    ],
    toolbar: 'undo redo | formatselect | ' +
    'bold italic backcolor | alignleft aligncenter ' +
    'alignright alignjustify | bullist numlist outdent indent | ' +
    'removeformat | help',
  });
</script>
</body>
</html>
"""),
                    initialHeaders: {},
                    initialOptions: InAppWebViewGroupOptions(
                      crossPlatform: InAppWebViewOptions(
                        debuggingEnabled: true,
                      ),
                      android: AndroidInAppWebViewOptions(
                        builtInZoomControls: true
                      )
                    ),
                    onWebViewCreated: (InAppWebViewController controller) {
                      webView = controller;
                    },
                    onLoadStart: (InAppWebViewController controller, String url) {

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

                    }
                  ))
            ])),
      ),
    );
  }
}

Screenshot:截屏:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM