How to render a local HTML file with flutter dart

2020-02-04 06:08发布

I want to render a local HTML file stored in my phone memory in webview using flutter and dart.

6条回答
ゆ 、 Hurt°
2楼-- · 2020-02-04 06:24

Here is an answer with a little more detail. I am using the webview_flutter plugin from the Flutter Team.

Steps

  1. Add the dependency to pubspec.yaml:

    dependencies:
      webview_flutter: ^0.3.4
    
  2. Put an html file in the assets folder (see this). I'll call it help.html.

  3. Get the html string in code and add it to the 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());
      }
    }
    

Notes:

  • I needed to set the encoding to UTF-8 because I was getting a crash for non-ASCII characters.
  • In iOS you need to add the key io.flutter.embedded_views_preview as true in the Info.plist file. Check the docs for any update on this requirement.

See also

查看更多
来,给爷笑一个
3楼-- · 2020-02-04 06:31

You can use my plugin flutter_inappwebview, which has a lot of events, methods, and options compared to other plugins!

To load an html file from your assets folder, you need to declare it in the pubspec.yaml file before use it (see more here).

Example of a pubspec.yaml file:

...

# 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

...

After that, you can simply use the initialFile parameter of the InAppWebView widget to load index.html into the WebView:

import 'dart:async';

import 'package:flutter/material.dart';

import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  runApp(new MyApp());
}

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

class _MyAppState extends State<MyApp> {

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: InAppWebViewPage()
    );
  }
}

class InAppWebViewPage extends StatefulWidget {
  @override
  _InAppWebViewPageState createState() => new _InAppWebViewPageState();
}

class _InAppWebViewPageState extends State<InAppWebViewPage> {
  InAppWebViewController webView;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: Text("InAppWebView")
        ),
        body: Container(
            child: Column(children: <Widget>[
              Expanded(
                child: Container(
                  child: InAppWebView(
                    initialFile: "assets/index.html",
                    initialHeaders: {},
                    initialOptions: InAppWebViewWidgetOptions(
                      inAppWebViewOptions: InAppWebViewOptions(
                        debuggingEnabled: true,
                      ),
                    ),
                    onWebViewCreated: (InAppWebViewController controller) {
                      webView = controller;
                    },
                    onLoadStart: (InAppWebViewController controller, String url) {

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

                    },
                  ),
                ),
              ),
            ]))
    );
  }
}
查看更多
够拽才男人
4楼-- · 2020-02-04 06:31

unzip the apk package,I found the reason: path is wrong;

For Android:

"assets/test.html" == "file:///android_asset/flutter_assets/assets/test.html"

so,just like this:

WebView(
    initialUrl: "file:///android_asset/flutter_assets/assets/test.html",
    javascriptMode: JavascriptMode.unrestricted,
  )

you can load "assets/test.html".

查看更多
一夜七次
5楼-- · 2020-02-04 06:32

You can pass a data URI

Uri.dataFromString('<html><body>hello world</body></html>', mimeType: 'text/html').toString()

or you can launch a web server inside Flutter and pass an URL that points to the IP/port the server serves the file from.

See also the discussion in https://github.com/fluttercommunity/flutter_webview_plugin/issues/23

See https://flutter.io/docs/development/ui/assets-and-images#loading-text-assets about how to load a string from assets.

See https://flutter.io/docs/cookbook/persistence/reading-writing-files for how to read other files.

查看更多
迷人小祖宗
6楼-- · 2020-02-04 06:32

I have the same problem; this is how I solved it.

  1. Add webview_flutter to your project dependencies:

    webview_flutter: 0.3.14+1

  2. Create a WebViewController inside your screen/stateful widget

    WebViewController _controller;

  3. Implement the WebView and assign a value to the _controller using the onWebViewCreated property. Load the HTML file.

    WebView(
        initialUrl: '',
        onWebViewCreated: (WebViewController webViewController) async {
          _controller = webViewController;
          await loadHtmlFromAssets('legal/privacy_policy.html', _controller);
        },
      )
  1. Implement the function to load the file from the asset folder
    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());
    }
查看更多
▲ chillily
7楼-- · 2020-02-04 06:39

@Suragch, your code doesn't work as you posted it, it says localUrl was called on null. _loadHtmlFromAssets needs to be called after assigning the controller :

onWebViewCreated: (WebViewController webViewController) {
          _controller = webViewController;
          _loadHtmlFromAssets();
        }

Then it works fine :)

查看更多
登录 后发表回答