flutter_local_notificationsのonSelectNotification属性でNavigatorを使うとき、contextを参照できない

※当サイトは、アフィリエイト広告を利用しています

結論:GlobalKey経由で「Navigator」を起動する

2022/5/7 Flutter エラー・バグ日記

 

ローカル通知を実装できる「flutter_local_notifications」パッケージを用いると、通知タップ時に特定の画面を開く処理を書けるのだが、「Navigator」の「push」メソッドを使おうとすると「Navigator.of(context).push」のように、「context」が必要になる。

 

本記事はライトな日記思考で書いているので、詳細説明はしておらず、基本、テキストのみで画像とかは載せておりません。。m(_ _)m

解説記事ではないため、解決していない内容や、その時々の間違った解釈を述べてしまっている可能性が大いにありますので、何卒、ご了承ください。

 

しかし、通知タップ処理を設定する「onSelectNotification」属性は、「flutter_local_notifications」の初期化処理を行う「initialize」メソッドの引数であり、この「initialize」メソッドを、アプリ起動時にmain関数から呼び出していたため、この段階だとまだ「context」を渡せない。。。(「undefined name」のエラーになってしまう)。

 

buildメソッドを回して「context」を生成してから、「initialize」メソッドに渡してもよいが、状態管理にMVVMモデルを採用し、Model層に通知関係の処理(「initialize」メソッドなど)を書いていたため、View層→ViewModel層→Model層と「context」を渡していくと、とても煩雑になる。。。

 

調べると、こちらに全く同じ疑問を持った方からのイシュー情報があった。

 

 

コメントとして、「didChangeDependencies」を用いると「context」取得できる、という内容があるが、リプライにもあるとおり、自分も使い方がよくわからなかった。。。

 

ただ、本イシューの最後から、下記イシューに飛んでおり、こちらではGlobalKeyを使う方法が提案されていた。

 

 

こちらの方法は分かりやすかったので、早速、以下のようにGlobalKeyを宣言し、

 

// View層とModel層で共有できるようにするため、グローバルで定義
final GlobalKey<NavigatorState> navigatorKeyO = GlobalKey<NavigatorState>();

 

View層の「MaterialApp」の「navigatorKey」属性に上記GlobalKeyを設置。

 

MaterialApp(
        navigatorKey: navigatorKeyO,

 

続いて「onSelectNotification」属性のメソッドを下記のように規定したら、無事、通知タップから指定画面(下記の例では「TestScreenO」)を開くことができた。

 

/// initializeメソッドのonSelectNotification属性に設置するメソッド
  Future<void> selectNotificationO(String? payloadO) async {
    // GlobalKey経由で Navigator を起動する
    navigatorKeyO.currentState!.push(
        MaterialPageRoute(
          builder: (context) {
            // payloadOは、zonedScheduleメソッド(本記事では割愛)で設定する、通知から渡される値
            return TestScreenO(payloadO: payloadO!);
          },
        ),
    );
  }

  

ちなみに、前述のイシューでは、「pushNamed」メソッドを使っているが、自分は使い慣れている「.push(MaterialPageRoute(builder:・・・{・・・}))」を使った。

 

MaterialPageRouteのbuilderに設定している「context」は、ここで生成するものなので、「undefined」のエラーにはならず、問題なかった(引数省略はできないが、「(context)」は別名称でも良いし、遷移先にcontextを渡す必要がない場合は「(_)」とすることもできる)。

 

リリースしたアプリ(全てFlutterで開発)

 

個人アプリ開発で役立ったもの

おすすめの学習教材

超初心者向けでオススメな元Udemyの講座/

 

 \キャンペーン時を狙えば安価で網羅的な内容が学べる(日本語訳あり)/

 

\Gitの基礎について無料で学べる/

 

おすすめの学習書籍

実用的image_pickerに関してかなり助けられた/

 

Dartの基礎文法を素早くインプットできる/


Dart入門 - Dartの要点をつかむためのクイックツアー

タイトルとURLをコピーしました