3

Is there any possibility to load complete website (including associated files) from local assets ? I tried it with flutter plugin webview_flutter and loaded index.html.

  Future<String> loadLocal() async {
    return await rootBundle.loadString('assets/mywebsite/index.html');
  }

only html code is being rendered and associated javascripts are not working.

Olian04
  • 6,480
  • 2
  • 27
  • 54
Shahzad Akram
  • 4,586
  • 6
  • 32
  • 65

3 Answers3

1

You can follow https://github.com/flutter/flutter/issues/27086

In the meantime you can implement a web server in Dart that serves files from assets and point the webview to that integrated web server.

https://medium.com/@segaud.kevin/facebook-oauth-login-flow-with-flutter-9adb717c9f2e is about how to do that in Dart.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
0

You can try also my plugin flutter_inappwebview, which is 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.

To load a complete website from assets, you need to declare the corresponding files in the 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
    - assets/page-1.html
    - assets/page-2.html
    - assets/js/
    - assets/css/
    - assets/images/

...

Then, you can load your index.html file using initialFile parameter of the InAppWebView widget:

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) {

                    },
                    onConsoleMessage: (InAppWebViewController controller, ConsoleMessage consoleMessage) {
                      print(consoleMessage.message);
                    },
                  ),
                ),
              ),
            ]))
    );
  }
}

In your index.html you will have something like that:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <!-- this is a css file inside the assets folder -->
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <!-- this is a javascript file inside the assets folder -->
    <script src="js/main.js"></script>
</body>
</html>
Lorenzo Pichilli
  • 2,896
  • 1
  • 27
  • 50
  • Your example doesn't work. I just spent 2 hours on it and on your github repo and still couldn't get it to work. – Enrico Dias May 02 '20 at 15:23
  • Do you know how to load the HTML from String but getting the image resource from assets? Please refer to https://github.com/flutter/flutter/issues/27086#issuecomment-625278513 – user2872856 May 07 '20 at 14:33
0

I've been able to do this but it's working only in Android. I've used the InAppWebView library in the following way :

 child: Container(
              child: InAppWebView(
                initialFile: "images/test.html",
                initialHeaders: {},
                onWebViewCreated: (InAppWebViewController controller) {
                  webView = controller;
                },
                onLoadStart: (InAppWebViewController controller, String url) {},
                onLoadStop: (InAppWebViewController controller, String url) {},
                onConsoleMessage: (InAppWebViewController controller,
                    ConsoleMessage consoleMessage) {
                  print(consoleMessage.message);
                },
              ),
            ),

The html file, including the related files have been added in the project assets.

Florin Laudat
  • 131
  • 1
  • 7