[Flutter]グーグルフォームをオリジナルデザインにする。
以前作ったwebviewでグーグルフォームを表示するプログラムをちょっとだけ変えます。
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:xxx/provider/contact_us_provider.dart';
import 'package:webview_flutter/webview_flutter.dart';
class ContactUsPage extends HookWidget {
@override
Widget build(BuildContext context) {
final cusp = useProvider(contactUsStateProvider);
final contactUsState = useProvider(contactUsStateProvider.state);
final Completer<WebViewController> _controller =
Completer<WebViewController>();
useEffect(() {
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
cusp.check();
return () {};
}, []);
return Scaffold(
appBar: AppBar(
title: Text('お問い合わせ'),
),
body: Builder(builder: (BuildContext context) {
return contactUsState.connectionStatus == true
? IndexedStack(
index: contactUsState.position,
children: [
WebView(
initialUrl:'',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated:
(WebViewController webViewController) async {
_controller.complete(webViewController);
// HTMLファイルのURL(ローカルファイルの情報)をControllerに追加する処理
await _loadHtmlFromAssets(_controller);
},
onPageFinished: cusp.doneLoading, // indexを0にしてWebViewを表示
onPageStarted:
cusp.startLoading, // indexを1にしてプログレスインジケーターを表示
),
// プログレスインジケーターを表示
Container(
child: Center(
child: CircularProgressIndicator(
backgroundColor: Colors.blue),
),
),
],
)
// インターネットに接続されていない場合の処理
: SafeArea(
child: Center(
child: Column(
children: [
Padding(
padding: EdgeInsets.only(
top: 120,
bottom: 20,
),
child: Container(),
),
Padding(
padding: EdgeInsets.only(
bottom: 20,
),
child: Text(
'インターネットに接続されていません',
),
),
],
),
),
);
}),
);
}
/// HTMLファイルを読み込む処理(非同期)
Future _loadHtmlFromAssets(controller) async {
//HTMLファイルを読み込んでHTML要素を文字列で返す
final fileText = await rootBundle.loadString('assets/html/contact_us.html');
final String contentBase64 =
base64Encode(const Utf8Encoder().convert(fileText));
await controller.loadUrl('data:text/html;base64,$contentBase64');
}
}
このまま動かしてもエラー出る。
pubspec.yamlに以下を追加。htmlファイルはassets/html/内に配置している。
assets:
- assets/html/
追加して動かしてみたけどメソッドが無いエラー。
Unhandled Exception: NoSuchMethodError: Class '_AsyncCompleter<WebViewController>' has no instance method 'loadUrl'
数時間経過。。。
onWebViewCreated:
(WebViewController webViewController) async {
_controller.complete(webViewController);
// HTMLファイルのURL(ローカルファイルの情報)をControllerに追加する処理
await _loadHtmlFromAssets(_controller);
},
↓
onWebViewCreated:
(WebViewController webViewController) async {
_controller.complete(webViewController);
// HTMLファイルのURL(ローカルファイルの情報)をControllerに追加する処理
await _loadHtmlFromAssets(webViewController);
},
_loadHtmlFromAssets()の引数を変えて通った。とりあえずエラー出無さそうなのでこのままで。
contact_us.htmlは以下のようになっています。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- ビューポートの設定 -->
<meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<body>
<form action="https://docs.google.com/forms/u/0/d/e/xxxxktyO7KfMEbVH33oW5526Xy-w/formResponse" target="_self" method="POST" id="mG61Hd" jsmodel="TOfxwf Q91hve" data-response="%.@.[]]" data-first-entry="0" data-last-entry="2" data-is-first-page="true">
<h1>お問い合わせ</h1>
<!-- 件名入力 -->
<div class="p-formGroup u-mb20">
<label for="subject">件名</label>
<input name="entry.2345677" type="text" required="required" id="textfield" class="g_form" placeholder="件名">
</div>
<!--//End 件名入力 -->
<!-- お問い合わせ内容入力 -->
<div class="p-formGroup u-mb20">
<label for="content">お問い合わせ内容</label>
<textarea name="entry.123456789" required class="g_form_text" id="entry.952897594"
placeholder="お問い合わせ"></textarea>
</div>
<!--//End お問い合わせ内容入力 -->
<!-- 送信 -->
<div class="p-form__btn">
<input type="submit" value="送信する">
</div>
<!--//End 送信 -->
</form>
</body>
</html>
ここで重要なのは、form action='xxxx'、input name="entry.xxxx"、textarea name="entry.xxxx"この値をグーグルフォームの値と合わせていく。詳しくわ(2020年6月最新版【仕様変更対応済み】Googleフォームを好きなようにカスタマイズする方法)をご覧ください。
これでローカルにあるコンタクトフォームのhtmlをflutterからwebviewを通して呼び出して、グーグルフォームと連携することができる。