【问题标题】:Is there a way to import external scripts in Flutter WebView有没有办法在 Flutter WebView 中导入外部脚本
【发布时间】:2020-07-08 06:19:03
【问题描述】:

我正在尝试将外部脚本加载到 Flutter WebView 中,但它似乎不起作用。特别是关于 tinyMCE。所以目的是在一个AlertDialog中打开一个富文本编辑器,里面有WebView。这可能吗?

以下是我的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>

这就是我的小部件:

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();
  }
}

我在控制台中得到以下日志:

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

任何帮助将不胜感激。谢谢!

【问题讨论】:

    标签: flutter webview flutterwebviewplugin


    【解决方案1】:

    要使 TinyMCE 正常工作,您还需要在 HTML 的开头添加 &lt;!DOCTYPE html&gt;(请参阅 https://community.tiny.cloud/communityQuestion?id=9064N000000MvpyQAC)。

    你也可以试试我的插件flutter_inappwebview,如果它不适用于webview_flutter。 它是一个 Flutter 插件,可让您添加内联 WebView 或打开应用内浏览器窗口,并提供大量事件、方法和选项来控制 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) {
    
                        }
                      ))
                ])),
          ),
        );
      }
    }
    

    截图:

    【讨论】:

    • 我正在尝试在 Flutter Web 中使用您的解决方案,但是使用上面的代码我得到以下错误:1)onLoadStart 和 onLoadStop 函数的第二个参数是 Uri 而不是 String 2)在浏览器中,我得到“flutter_inappwebview 插件尚不支持targetPlatform.windows”
    • Ciao Francesco,如您所见,这个问题很老了,与此同时,插件也在进化。此示例适用于旧版本 4.0.0+4。对于第一个错误:您可以从参数中删除类型或将其更改为Uri(通常,URL 现在有Uri 输入新版本5!)。对于第二个错误:是的,该插件目前仅支持 Android 和 iOS。我还会添加对 MacOS、Linux 和 Windows 的支持,但这需要很多时间
    猜你喜欢
    • 1970-01-01
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    • 2023-01-27
    • 2010-10-10
    • 1970-01-01
    • 1970-01-01
    • 2017-03-23
    相关资源
    最近更新 更多