2つ以上のFloatingActionButtonを使った場合の画面遷移の注意点

Material designでは、1画面に1FABが推奨。

まとめ

  • 2つ以上のFloatingActionButton(FAB)を使って、画面遷移しようとすると例外が投げられる
  • 解決策は、UniqueなheroTagを設定すること
  • 基本的にMaterial designでは1画面につき1つだけFABの使用を推奨している

2つ以上のFloatingActionButton(FAB)を使って、画面遷移しようとすると例外が投げられる

以下のCodeでは2つ以上のFloatingActionButtonがあります。
この状態でRaisedButtonを押すと、うまく画面遷移できず、Errorになります。
以下のCodeを元にしています。

Navigate to a new screen and back

images

import 'package:flutter/material.dart';
void main() {
  runApp(MaterialApp(
    title: 'Named Routes Demo',
    initialRoute: '/',
    routes: {
      '/': (context) => FirstScreen(),
      '/second': (context) => SecondScreen(),
    },
  ));
}
class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Title'),
        ),
        body: Center(
          child: RaisedButton(
            child: Text('Launch screen'),
            onPressed: () {
              Navigator.pushNamed(context, '/second');
            },
          ),
        ),
        floatingActionButton: Column(
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            FloatingActionButton(
              child: Icon(
                Icons.shopping_cart,
                color: Colors.white,
              ),
              onPressed: () {},
            ),
            FloatingActionButton(
              child: Icon(
                Icons.share,
                color: Colors.white,
              ),
              onPressed: () {},
            ),
          ],
        ),
      ),
    );
  }
}
class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Screen"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Go back!'),
        ),
      ),
    );
  }
}

Errorになることは、FloatingActionButton classの説明にもしっかり記載されています。

If more than one floating action button is used within a Route, then make sure that each button has a unique heroTag, otherwise an exception will be thrown.

FloatingActionButton class - material library - Dart API

解決策は、UniqueなheroTagを設定すること

上の例から、それぞれのFABにUniqueなheroTagを設定しました。
変更はそれだけです。
この状態でRaisedButtonを押すと、Second Screenに遷移できます。

import 'package:flutter/material.dart';
void main() {
  runApp(MaterialApp(
    title: 'Named Routes Demo',
    initialRoute: '/',
    routes: {
      '/': (context) => FirstScreen(),
      '/second': (context) => SecondScreen(),
    },
  ));
}
class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Title'),
        ),
        body: Center(
          child: RaisedButton(
            child: Text('Launch screen'),
            onPressed: () {
              Navigator.pushNamed(context, '/second');
            },
          ),
        ),
        floatingActionButton: Column(
          mainAxisAlignment: MainAxisAlignment.end,
          children: <Widget>[
            FloatingActionButton(
              heroTag: 'cart',
              child: Icon(
                Icons.shopping_cart,
                color: Colors.white,
              ),
              onPressed: () {},
            ),
            FloatingActionButton(
              heroTag: 'share',
              child: Icon(
                Icons.share,
                color: Colors.white,
              ),
              onPressed: () {},
            ),
          ],
        ),
      ),
    );
  }
}
class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Screen"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Go back!'),
        ),
      ),
    );
  }
}

Second screen

基本的に1画面につき1つだけのFAB

Material designでは、1画面に1FABが推奨。
重要な機能が複数ある場合にのみ、複数のFABを使用しても良いらしい。

Buttons: floating action button

Two FABs

heroTag property - FloatingActionButton class - material library - Dart API

The material design specification recommends only using one floating action button per screen.


この記事が誰かの手助けになることを祈っています。


スポンサーリンク

最終更新 2021/12/03: Update (424a635)