概要
Next.js上で扱うデータをFlutterに渡したかったので調査しました。なお、WebアプリであればNext.jsである必要はありません。
環境
- Next.js 14.0.2
- React 18.0
- Flutter 3.13.9
- webview_flutte 4.4.2
セットアップ
以下のコマンドでプロジェクトを作成します。
npx create-next-app next_app
flutter create flutter_app
パッケージのインストール
Webページの表示にはwebview_flutterを使います。
flutter pub add webview_flutter
android/app/build.gradleのminSdkVersionが19より低い場合は、minSdkVersionを設定する必要があります。
実装
Next.jsからFlutterにデータを送信します。
Flutter側のコード
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() {
runApp(
MaterialApp(
theme: ThemeData(useMaterial3: true),
home: const WebViewApp(),
),
);
}
class WebViewApp extends StatefulWidget {
const WebViewApp({super.key});
@override
State<WebViewApp> createState() => _WebViewAppState();
}
class _WebViewAppState extends State<WebViewApp> {
late final WebViewController controller;
@override
void initState() {
super.initState();
const String webViewUrl = 'http://localhost:3000';
const String webViewName = 'flutterWebView';
controller = WebViewController()
..loadRequest(Uri.parse(webViewUrl))
..setJavaScriptMode(JavaScriptMode.unrestricted)
..addJavaScriptChannel(
webViewName,
onMessageReceived: (message) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(message.message)));
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter WebView'),
),
body: WebViewWidget(
controller: controller,
),
);
}
}
任意のチャンネル名を設定することができ、その名前がJavaScriptの呼び出し名になります。今回はチャンネル名をflutterWebView
としています。
Next.js側のコード
"use client";
export default function Home() {
const clickHandler = () => {
// @ts-ignore
flutterWebView.postMessage("Hello Flutter!");
};
return (
<div className="flex flex-col items-center justify-center min-h-screen py-2">
<div className="flex items-center justify-center">
<button
onClick={clickHandler}
className="bg-yellow-500 hover:bg-yellow-700 text-white font-bold py-2 px-4 rounded"
>
Flutterにデータを送る
</button>
</div>
</div>
);
}
検証
プロジェクトを立ち上げます。
npm run dev
flutter run
Javascript側で送信したメッセージをFlutterで受け取ったことが確認できると思います。
参考