【Flutter】No implementation found for method showToast on channel ...

ネコニウム研究所

PCを利用したモノづくりに関連する情報や超個人的なナレッジを掲載するブログ

【Flutter】No implementation found for method showToast on channel ...

2024-6-19 | ,

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!))

まとめ(感想文)

デスクトップアプリでも楽をしたかったんだけども、おそらくデスクトップアプリの場合は内部的にスナックバーが使われてると思われ。