LoginSignup
22
11

More than 3 years have passed since last update.

[Flutter]画面遷移で起きたエラー

Last updated at Posted at 2020-01-07

エラー内容

事象

画面遷移を実装していた時に遷移すると画面が真っ暗になる不具合に遭遇した
Flutter遷移失敗.gif

実装は以下のようになっていた

Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            RaisedButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) {
                      return SecondPage();
                  }),
                );
              },
              child: Text('Go Second'),
            ),
          ],
        ),
      ),
      floatingActionButton: Column(
        verticalDirection: VerticalDirection.up,
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Container( 
            margin: EdgeInsets.only(bottom: 16.0),
            child: FloatingActionButton(
              backgroundColor: Colors.redAccent,
              onPressed: _incrementCounter,
              child: Icon(Icons.add),
            ),
          ),
          Container(
            margin: EdgeInsets.only(bottom: 16.0),
            child: FloatingActionButton(
              backgroundColor: Colors.amberAccent,
              onPressed: _decrementCounter,
              child: Icon(Icons.remove),
            ),
          ),
          Container(
            margin: EdgeInsets.only(bottom: 16.0),
            child: FloatingActionButton(
              backgroundColor: Colors.green,
              onPressed: _deleteAll,
              child: Icon(Icons.delete),
            ),
          ),
        ],
      ),
    );
  }

ログをみてみると以下のようなエラーが発生していた

The following assertion was thrown during a scheduler callback:
There are multiple heroes that share the same tag within a subtree.

Within each subtree for which heroes are to be animated (i.e. a PageRoute subtree), each Hero must have a unique non-null tag.
In this case, multiple heroes had the following tag: <default FloatingActionButton tag>

Here is the subtree for one of the offending heroes: Hero
  tag: <default FloatingActionButton tag>
  state: _HeroState#6468c
When the exception was thrown, this was the stack: 
#0      Hero._allHeroesFor.inviteHero.<anonymous closure> (package:flutter/src/widgets/heroes.dart:265:11)
#1      Hero._allHeroesFor.inviteHero (package:flutter/src/widgets/heroes.dart:276:8)
#2      Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:295:21)
#3      SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:5433:14)
#4      Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:308:15)
...

ふむふむ、よくわからん(英語読めない)
FloatingActionButtonがどうのこうの言っている?

翻訳してみた

There are multiple heroes that share the same tag within a subtree.
サブツリー内で同じタグを共有する複数のヒーローがいます。

Flutterは複数のヒーローを認めていないらしい(冗談です)

いろいろ調べるとHeroClassと言うものがあるらしく、それらを複数使用する時はheroTagを指定してあげる必要があるらしい

解決

各FloatingActionButtonにheroTagを指定することで解決した

     floatingActionButton: Column(
        verticalDirection: VerticalDirection.up,
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Container(
            margin: EdgeInsets.only(bottom: 16.0),
            child: FloatingActionButton(
              heroTag: "hero1", // HeroTag設定
              backgroundColor: Colors.redAccent,
              onPressed: _incrementCounter,
              child: Icon(Icons.add),
            ),
          ),
          Container(
            margin: EdgeInsets.only(bottom: 16.0),
            child: FloatingActionButton(
              heroTag: "hero2", // HeroTag設定
              backgroundColor: Colors.amberAccent,
              onPressed: _decrementCounter,
              child: Icon(Icons.remove),
            ),
          ),
          Container(
            margin: EdgeInsets.only(bottom: 16.0),
            child: FloatingActionButton(
              heroTag: "hero3", // HeroTag設定
              backgroundColor: Colors.green,
              onPressed: _deleteAll,
              child: Icon(Icons.delete),
            ),
          ),
        ],
      ),

またHeroClassを使う時も単体であれば問題は内容だった
ボタンのコンポーネントを別のものに置き換えることでも解決した

↓ボタンを一つにした時
Flutter遷移0.gif

↓ボタンのコンポーネントを別のものに変更
Flutter遷移.gif

22
11
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
11