クラウドエンジニアがFlutterを学んでみた【ローカルHTML/CSSファイル読み込み編】

5 min読了の目安(約4500字TECH技術記事

どうも、スウェーデンでITエンジニアをしているあめぞう(@amezousan)です。

前回のクラウドエンジニアがFlutterを学んでみた【チュートリアル編】に続いて学んでいきます。

今世の中はものすごく便利になってきていてドラッグ&ドロップをするだけでモバイル専用のHTMLが生成できるノーコードツールが登場しています👉Shots

今回はその生成されたコードがFlutterで読み込めて表示できるかを検証していきます。

進め方の方針

以下の通り進めていきます。

  • Shotsで何が出来るのかを確認
  • FlutterでHTML読込方法を確認
  • 実際にFlutterで試してみる

Shotsで何が出来るのかを確認

結論から言うとお金を払わないとHTMLコードは生成できませんでした。色んなコンポーネントがiOS/Android または両方で使えるモノなど多数用意されているのですがHTML生成するためには有料会員になる必要があるようです。

今回はあくまで検証なのでトップページにあるDEMOのHTML, CSSを読み込ませる方向で進めていきます。

FlutterでHTML読込方法を確認

「how to load html files in flutter」でGoogle検索。トップ記事のほとんどが「WebView」を使え、と進めていますね。これはReact Nativeでも同じなのでその通りに従いましょう。

「How to」のキーワードは実装法を調べる際にものすごく便利です。

実際にFlutterで試してみる

フォルダ構造は以下の通り

my_app$ tree -d -L 2
.
├── android
│   ├── app
│   └── gradle
├── build
│   ├── 4c2bfcc41fcc9beb37f6c33d83865ddf
│   ├── app
│   ├── ios
│   └── kotlin
├── ios
│   ├── Flutter
│   ├── Runner
│   ├── Runner.xcodeproj
│   └── Runner.xcworkspace
├── lib
└── test

WebViewの設定

  1. https://pub.dev/packages/webview_flutter/install 」でWebViewのインストール方法を確認
  2. 前回チュートリアル時に作成した「my_app」で以下を実施
    * pubspec.yamlに追記
    dependencies:
      webview_flutter: ^1.0.1
    
    * Install
    $ flutter pub get
    
  3. exampleコードを真似して、lib/main.dartに以下を追記
    import 'package:webview_flutter/webview_flutter.dart';
    
    ...
    
    class WebViewExample extends StatelessWidget {
      
      Widget build(BuildContext context) {
        return WebView(
          initialUrl: 'https://flutter.dev',
        );
      }
    }
    
  4. $ flutter runを実行してiOS / Androidのシミュレータできちんと表示されていることを確認できました。

WebViewでHTMLファイルを読み込む

以下の記事を参考にしました。

  1. my_app配下にassetsフォルダを作成し以下の通りファイルを作成
    [index.html] shots.ai - DEMOのHTMLをコピーして以下の一行を追加
    ...
        <link
          rel="stylesheet"
          href="./css/style.css"
        />
      </head>
    ...
    
    [css/style.css] shots.ai - DEMOのCSSをそのままコピー。
    
  2. pubspec.yamlファイルに以下を追記
    ...
    flutter:
    
      assets:
        - assets/index.html
        - assets/css/
    ...
    
  3. HTMLを読み込ませることだけが目的なのでlib/main.dartを以下の通り書く。
    import 'dart:convert';
    
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'package:webview_flutter/webview_flutter.dart';
    
    void main() {
      runApp(MaterialApp(
        title: 'Navigation Basics',
        home: HelpScreen(),
      ));
    }
    
    class HelpScreen extends StatefulWidget {
      
      HelpScreenState createState() {
        return HelpScreenState();
      }
    }
    
    class HelpScreenState extends State<HelpScreen> {
      WebViewController _controller;
    
      
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text('Help')),
          body: WebView(
    	initialUrl: 'about:blank',
    	onWebViewCreated: (WebViewController webViewController) {
    	  _controller = webViewController;
    	  _loadHtmlFromAssets();
    	},
          ),
        );
      }
    
      _loadHtmlFromAssets() async {
        String fileText = await rootBundle.loadString('assets/index.html');
        _controller.loadUrl( Uri.dataFromString(
    	fileText,
    	mimeType: 'text/html',
    	encoding: Encoding.getByName('utf-8')
        ).toString());
      }
    }
    

全然CSSが反映されてません。困った...。WebViewでは出来ないのかも?

色々調べるとGithubのIssueが立ってますね。👉Load local assets like HTML and linked files in a Flutter app using WebView

要は「webview」単体だとできないよ、と言う事ですね。現時点で分かってるのは以下いずれかを選ぶとできそうと言う事。

InAppWebviewは今回求めてる事以上のものが出来そうですが少しオーバースペック気味なので「webview_flutter_plus」を使います。

チュートリアル通りに設定を進めて「Examlpe」のコードをそのまま使用すると以下の通り期待通りの表示が出来ました!

今回はこれでおしまいです。

最後に

Dart言語は何度見ても慣れないですね…。1つ分かってるのはサンプルコードをコピペして動くのは動くけど1つずつの意味を理解しないと全く成長できないと言う感覚がしています。

新しい言語を覚える際には慣れるまである程度の時間が掛かるのでしばらくは公式TutorialとFlutterのコア部分のソースコードを読みながら学習を進めたいと思います。

ではまた、Vi ses!