如何使用Flutter Dart WebView呈现本地HTML文件

Abd*_*rry 9 webview dart flutter flutter-layout

我想使用flutter和dart渲染存储在我的手机内存中的Webview中的本地HTML文件。

Gün*_*uer 17

您可以传递数据 URI

Uri.dataFromString('<html><body>hello world</body></html>', mimeType: 'text/html').toString()
Run Code Online (Sandbox Code Playgroud)

或者您可以在 Flutter 中启动一个 Web 服务器并传递一个指向服务器提供文件的 IP/端口的 URL。

另请参阅https://github.com/fluttercommunity/flutter_webview_plugin/issues/23 中的讨论

有关如何从资产加载字符串的信息,请参阅https://flutter.io/docs/development/ui/assets-and-images#loading-text-assets

有关如何读取其他文件,请参阅https://flutter.io/docs/cookbook/persistence/reading-writing-files

  • 编码: Encoding.getByName('utf-8') 也很有用 (2认同)

Sur*_*gch 13

这是一个更详细的答案。我正在使用Flutter团队的webview_flutter插件。

脚步

  1. 将依赖项添加到pubspec.yaml

    dependencies:
      webview_flutter: ^0.3.4
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将html文件放在assets文件夹中(请参阅参考资料)。我给它打电话help.html

  3. 获取代码中的html字符串并将其添加到webview。

    import 'dart:convert';
    
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'package:webview_flutter/webview_flutter.dart';
    
    
    class HelpScreen extends StatefulWidget {
      @override
      HelpScreenState createState() {
        return HelpScreenState();
      }
    }
    
    class HelpScreenState extends State<HelpScreen> {
      WebViewController _controller;
    
      @override
      Widget build(BuildContext context) {
        _loadHtmlFromAssets();
        return Scaffold(
          appBar: AppBar(title: Text('Help')),
          body: WebView(
            initialUrl: 'about:blank',
            onWebViewCreated: (WebViewController webViewController) {
              _controller = webViewController;
            },
          ),
        );
      }
    
      _loadHtmlFromAssets() async {
        String fileText = await rootBundle.loadString('assets/help.html');
        _controller.loadUrl( Uri.dataFromString(
            fileText,
            mimeType: 'text/html',
            encoding: Encoding.getByName('utf-8')
        ).toString());
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)

笔记:

  • 由于我们异步加载html文件,因此我将设置initialUrl为空字符串(null会导致异常)。我不知道这是否是标准做法,但似乎可行。
  • 我需要将编码设置为UTF-8,因为非ASCII字符崩溃了。我相信无论如何,UTF-8是网络的标准。
  • 在iOS中,您需要io.flutter.embedded_views_previewtrueInfo.plist文件中一样添加密钥。检查文档以了解有关此要求的任何更新。

也可以看看

  • @Suragch如何从webview中的html访问本地js文件?例如:`&lt;script type="text/javascript" src="froala_editor.pkgd.min.js"&gt;&lt;/script&gt;` (11认同)

小智 12

@Suragch,您的代码在您发布时不起作用,它说localUrl被调用了null_loadHtmlFromAssets需要在分配控制器后调用:

onWebViewCreated: (WebViewController webViewController) {
  _controller = webViewController;
  _loadHtmlFromAssets();
}
Run Code Online (Sandbox Code Playgroud)

然后它工作正常:)


ILY*_*bal 7

我也有同样的问题; 这就是我解决它的方法。

  1. 将 webview_flutter 添加到您的项目依赖项中:

    webview_flutter: 0.3.14+1

  2. 在您的屏幕/有状态小部件中创建一个 WebViewController

    WebViewController _controller;

  3. 实现 WebView 并使用 onWebViewCreated 属性为 _controller 分配一个值。加载 HTML 文件。

    WebView(
        initialUrl: '',
        onWebViewCreated: (WebViewController webViewController) async {
          _controller = webViewController;
          await loadHtmlFromAssets('legal/privacy_policy.html', _controller);
        },
      )
Run Code Online (Sandbox Code Playgroud)
  1. 实现从资产文件夹加载文件的功能
    Future<void> loadHtmlFromAssets(String filename, controller) async {
        String fileText = await rootBundle.loadString(filename);
        controller.loadUrl(Uri.dataFromString(fileText, mimeType: 'text/html', encoding: Encoding.getByName('utf-8')).toString());
    }
Run Code Online (Sandbox Code Playgroud)


Lor*_*lli 6

你可以使用我的插件flutter_inappwebview,与其他插件相比,它有很多事件、方法和选项!

要从资产文件夹加载 html 文件,您需要在pubspec.yaml使用它之前在文件中声明它(请参阅此处的更多信息)。

文件示例pubspec.yaml

...

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  assets:
    - assets/index.html

...
Run Code Online (Sandbox Code Playgroud)

之后,您可以简单地使用小部件initialFile的参数InAppWebView加载index.html到WebView中:

...

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  assets:
    - assets/index.html

...
Run Code Online (Sandbox Code Playgroud)


Hij*_*iji 6

您可以使用Flutter InAppWebView 插件。它将在应用程序内创建一个本地服务器,并将在 WebView 中运行 HTML 应用程序。启动你的服务器:

InAppLocalhostServer localhostServer = new InAppLocalhostServer();

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

//... ...

class _MyHomePageState extends State < MyHomePage > {

//... ...

  @override
  void dispose() {
    localhostServer.close();
    super.dispose();
  }
}
Run Code Online (Sandbox Code Playgroud)

然后在 WebView 中指向您的 localhost html 索引文件。

InAppWebView(
  initialUrlRequest: URLRequest(
          url: Uri.parse('http://localhost:8080/assets/index.html')),
),
Run Code Online (Sandbox Code Playgroud)

在许多情况下,它对很多人不起作用,因为他们忘记将所有文件夹添加为文件中的资产pubspec.yaml。例如,您需要指定所有文件夹和索引文件,如下所示:

  assets:
    - assets/index.html
    - assets/css/
    - assets/images/
    - assets/js/
    - assets/others/
Run Code Online (Sandbox Code Playgroud)

您可以查看本教程以获取更多详细信息。