[Flutter]お問い合わせフォームを作りたくてGoogleフォームをWebViewで表示させる
【Flutter】WebViewで問い合わせを実装する【コピペでOK】を参考にしました。
SDK versionは1.22.2、webview_flutter: ^1.0.5
webview_flutterが古いヴァージョンだとios/Runner/Info.plistに、io.flutter.embedded_views_previewを追記しなければならなかったが、その必要はもうない。
state
import 'package:flutter/foundation.dart'; // *.freezed.dartで必要なのでimportしておく
import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'contact_us.freezed.dart';
@freezed
abstract class ContactUsState with _$ContactUsState {
const factory ContactUsState({
@Default(1) int position,
bool connectionStatus,
}) = _ContactUsState;
}
provider
import 'dart:io';
import 'package:hooks_riverpod/all.dart';
import 'package:xxx/entity/contact_us.dart';
import 'package:state_notifier/state_notifier.dart';
final contactUsStateProvider =
StateNotifierProvider((_) => ContactUsStateProvider());
class ContactUsStateProvider extends StateNotifier<ContactUsState> {
ContactUsStateProvider() : super(const ContactUsState());
doneLoading(String url) {
state = state.copyWith(position: 0);
}
startLoading(String url) {
state = state.copyWith(position: 1);
}
// インターネット接続チェック
Future check() async {
try {
final result = await InternetAddress.lookup('google.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
state = state.copyWith(connectionStatus: true);
}
} on SocketException catch (_) {
state = state.copyWith(connectionStatus: false);
}
}
}
page
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.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:
'https://docs.google.com/forms/d/e/...',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
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(
'インターネットに接続されていません',
),
),
],
),
),
);
}),
);
}
}
iosなら問題なく動いたけど、androidで試すと以下のメッセージが永遠と吐き出される
D/EGL_emulation(25147): eglMakeCurrent: 0xe7947ac0: ver 3 0 (tinfo 0xdeab4d80)
D/EGL_emulation(25147): eglMakeCurrent: 0xe7947ac0: ver 3 0 (tinfo 0xdeab4d80)
E/gralloc_ranchu(25147): updateHostColorBuffer: Unexpected DMA
E/ (25147): lockAndWriteDma: ERROR: No DMA context bound!
E/gralloc_ranchu(25147): updateHostColorBuffer: Unexpected DMA
E/ (25147): lockAndWriteDma: ERROR: No DMA context bound!
D/eglCodecCommon(25147): setVertexArrayObject: set vao to 1 (1) 4 9
D/eglCodecCommon(25147): setVertexArrayObject: set vao to 0 (0) 4 5
起動し直して、再度開いたら相変わらずメッセージは吐き出され続けるけど、ページは開けて、フォームも送れている。。
D/EGL_emulation( 4670): eglMakeCurrent: 0xe7c49220: ver 3 0 (tinfo 0xd07cb690)
D/EGL_emulation( 4670): eglMakeCurrent: 0xe7c49220: ver 3 0 (tinfo 0xd07cb690)
D/eglCodecCommon( 4670): setVertexArrayObject: set vao to 1 (1) 4 9
D/eglCodecCommon( 4670): setVertexArrayObject: set vao to 0 (0) 4 5
D/EGL_emulation( 4670): eglMakeCurrent: 0xe7c49220: ver 3 0 (tinfo 0xd07cb690)
D/EGL_emulation( 4670): eglMakeCurrent: 0xe7c49220: ver 3 0 (tinfo 0xd07cb690)
D/eglCodecCommon( 4670): setVertexArrayObject: set vao to 1 (1) 4 9
D/eglCodecCommon( 4670): setVertexArrayObject: set vao to 0 (0) 4 5
吐き出されるメッセージも少し変わっていた。エラーの文字はないからこれでいいのか?webviewを開いている間メッセージが永遠に垂れ流されるのは気持ち悪いけど、とりあえず動くのでOKと言うことで