Flutter: The following GlobalKey was specified multiple times in the widget tree. のエラー
結論:GlobalKeyをグローバル宣言ではなく「StatefulWidget」の「〜State」クラス内の宣言に修正
2022/5/5 Flutter エラー・バグ日記
Drawerのアイコンを変更するため、こちらの記事などを参考に、GlobalKeyを導入していたが、「Navigator」で画面の再読み込み処理を入れると、表題のエラーが発生した。
エラー文は以下のとおり。
Duplicate GlobalKey detected in widget tree.
The following GlobalKey was specified multiple times in the widget tree. This will lead to parts of the widget tree being truncated unexpectedly, because the second time a key is seen, the previous instance is moved to the new location. The key was:
[LabeledGlobalKey・・・]
This was determined by noticing that after the widget with the above global key was moved out of its previous parent, that previous parent never updated during this frame, meaning that it either did not update at all or updated before the widget was moved, in either case implying that it still thinks that it should have a child with that global key.
The specific parent that did not update after having one or more children forcibly removed due to GlobalKey reparenting is:
Listener(listeners: [down], behavior: deferToChild, renderObject: RenderPointerListener#69876)
A GlobalKey can only be specified on one widget at a time in the widget tree.
When the exception was thrown, this was the stack:
画面を再読み込みする際に、GlobalKeyが何度も宣言されてしまい、以前に宣言されたGlobalKeyが設置されているWidgetを削除せざるを得なくなる、、みたいな問題だろうか(違っているかも知れませんが、、)。
GlobalKeyの宣言文は、1箇所にしか書いておらず、
final GlobalKey<ScaffoldState> scaffoldKeyO = GlobalKey<ScaffoldState>();
のように記述していた。
ググってみると、こちらの情報に、「final」や「static」を削除すると解消する、と書かれていたので、試してみるも変わらず。
逆にこちらの情報だと「final」はつけるべき、とある(つけても解消はしないようだが、、、)。
更に調べると、こちらやこちらのページに、GlobalKeyを設定するWidgetのプロパティを、「key:」ではなく「refKey:」にすると良い、という情報もあった。
しかし、そもそもWidgetに「refKey:」というプロパティを用いること自体ができない。。。
深みにハマりつつあったが、ネットにあるGlobalKeyの使用例を見ると、「StatefulWidget」の「〜State」クラス内で宣言されているのに対し、自分の場合はクラスの外側で、グローバルなインスタンスとして宣言していることに気づいた。
そこで、宣言文をクラス内に移動させた上で実行すると、無事、エラーが解消された。
"Global"という名前から、てっきりグローバル変数的に宣言する必要があるのでは、と勘違いしていた。。
その後、こちらの記事を拝見し、そもそも「GlobalKey」は、「StatefulWidget」の状態を外部から参照するために用いるものである、ということを今更ながら理解(なので、「StatefulWidget」内で宣言する必要があるのだろう)。
リリースしたアプリ(全てFlutterで開発)
個人アプリ開発で役立ったもの
おすすめの学習教材
\超初心者向けでオススメな元Udemyの講座/
\キャンペーン時を狙えば安価で網羅的な内容が学べる(日本語訳あり)/
\Gitの基礎について無料で学べる/
おすすめの学習書籍
\実用的。image_pickerに関してかなり助けられた/
\Dartの基礎文法を素早くインプットできる/