Flutterのパッケージfluttertoast
を使ってトーストを表示しようとして発生するUnhandled Exception: MissingPluginException(No implementation found for method showToast on channel PonnamKarthik/fluttertoast)
をなんとかしたい!
概要
今回の記事では、Flutterのパッケージfluttertoast
を使ってトーストを表示しようとして発生するUnhandled Exception: MissingPluginException(No implementation found for method showToast on channel PonnamKarthik/fluttertoast)
をなんとかする手順を掲載する。
仕様書
環境
- Android Studio Jellyfish | 2023.3.1 Patch 2
- Flutter 3.19.6
手順書
fluttertoast
を使うとBuildContext
を使わなくてもトーストを表示できるのでめちゃ楽!とか思ってたんだけどもこれってモバイル(Android、iOS)とWEBアプリのみでデスクトップアプリではスナックバーと同様でMaterialApp
の中のScaffold
で作られてるBuildContext
を使う必要がある。
デスクトップアプリでfluttertoast
を使ってトーストを表示する例。
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
body: const FluttertoastSample2()
)
)
);
}
class FluttertoastSample2 extends StatelessWidget {
const FluttertoastSample2({super.key});
@override
Widget build(BuildContext context) {
FToast fToast = FToast();
fToast.init(context);
return SafeArea(
child: Center(
child: SizedBox(
width: double.infinity,
child: TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.blue,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
),
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
),
onPressed: () => {
fToast.showToast(
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 24.0, vertical: 12.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
color: Colors.greenAccent,
),
child: const Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.check),
SizedBox(
width: 12.0,
),
Text("This is a Custom Toast"),
],
),
),
gravity: ToastGravity.BOTTOM,
toastDuration: Duration(seconds: 2),
)
},
child: const Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
child: Text("Show Toast",
style: TextStyle(fontSize: 16.0, color: Colors.white)),
),
),
),
),
);
}
}
めんどい!これならデスクトップアプリに対応させる場合は標準のスナックバーを使った方が楽かも?!
スナックバーの時と同様にGlobalKey
を使う方法もある。
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
void main() {
runApp(FluttertoastSample3());
}
class FluttertoastSample3 extends StatelessWidget {
const FluttertoastSample3({super.key});
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
@override
Widget build(BuildContext context) {
FToast fToast = FToast();
fToast.init(ScaffoldMessenger.of(navigatorKey.currentContext!));
return
MaterialApp(
home: Scaffold(
body: SafeArea(
child: Center(
child: SizedBox(
width: double.infinity,
child: TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.blue,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4)),
),
padding: const EdgeInsets.fromLTRB(0, 0, 0, 0),
),
onPressed: () => {
fToast.showToast(
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 24.0, vertical: 12.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
color: Colors.greenAccent,
),
child: const Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.check),
SizedBox(
width: 12.0,
),
Text("This is a Custom Toast"),
],
),
),
gravity: ToastGravity.BOTTOM,
toastDuration: Duration(seconds: 2),
)
},
child: const Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
child: Text("Show Toast",
style: TextStyle(fontSize: 16.0, color: Colors.white)),
),
),
),
),
),
),
),
navigatorKey: navigatorKey,
);
}
}
GlobayKey
からBuildContext
を取得する感じ。
fToast.init(ScaffoldMessenger.of(navigatorKey.currentContext!))
まとめ(感想文)
デスクトップアプリでも楽をしたかったんだけども、おそらくデスクトップアプリの場合は内部的にスナックバーが使われてると思われ。