🐙

Flutterで複数のFloatingActionButtonを表示する方法

2020/12/12に公開

方法

ScaffoldのfloatingActionButtonパラメータは、FloatingActionButtonに限らず、Widgetを取ることができます。
なので、縦に2つ並べたい場合は次のようにCloumnで囲みます。

import 'package:flutter/material.dart';
import 'package:gap/gap.dart';

class HomePage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          FloatingActionButton(
            child: const Icon(
              Icons.favorite,
            ),
            onPressed: () {},
          ),
          Gap(
            16,
          ),
          FloatingActionButton(
            child: const Icon(
              Icons.add,
            ),
            onPressed: () {},
          ),
        ],
      ),
    );
  }
}

ただ、このままだと次のようなエラーが出ることがあります。

════════ Exception caught by scheduler library ═════════════════════════════════════════════════════
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#a4447
When the exception was thrown, this was the stack: 
#0      Hero._allHeroesFor.inviteHero.<anonymous closure> (package:flutter/src/widgets/heroes.dart:268:11)
#1      Hero._allHeroesFor.inviteHero (package:flutter/src/widgets/heroes.dart:279:8)
#2      Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:298:21)
#3      SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6105:14)
#4      Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:311:15)
...
════════════════════════════════════════════════════════════════════════════════════════════════════

そうした場合は、次のように各FloatingActionButtonにheroTagを設定します。

...
children: [
  FloatingActionButton(
    heroTag:'fav',
    child: const Icon(
      Icons.favorite,
    ),
    onPressed: () {},
  ),
  Gap(
    16,
  ),
  FloatingActionButton(
    heroTag:'add',
    child: const Icon(
      Icons.add,
    ),
    onPressed: () {},
  ),
],
...

FloatingActionButtonが2つ表示できました。

参考文献

More than One Floating Action Button in one page | by Rohan Maity | RotBolt | Medium
flutter - There are multiple heroes that share the same tag within a subtree - Stack Overflow

Discussion