【Flutter】Floating Action Buttonのカスタマイズ方法

はじめに

FloatingActionButton(FAB)は、アプリケーションの中で重要な役割を果たす主要なアクションを強調する目的で使用される丸いボタンです。しかし、その魅力を最大限に引き出すためには、適切な設置場所やカスタマイズ方法を理解し、効果的に利用することが重要です。この記事では、Flutterを使ったアプリ開発でFABの追加やカスタマイズ方法について詳しく解説し、ユーザビリティやアクセシビリティを向上させるためのベストプラクティスをご紹介します。アプリケーション開発において、ユーザーにとって快適な体験を提供するために、ぜひFABの活用を検討してみてください。

FloatingActionButtonの基本

FloatingActionButtonとは

FloatingActionButton(FAB)は、画面上で主要なアクションを表す丸いボタンです。このボタンは、ユーザーインターフェースの特定の部分に目立つように配置され、アプリの主要な機能を素早くアクセスできるようにすることを目的としています。

FABの追加方法

FABの追加は簡単で、floatingActionButtonプロパティを使ってScaffoldウィジェットに設定するだけです。以下に簡単な例を示します。

Scaffold(
  appBar: AppBar(
    title: Text('FAB Example'),
  ),
  body: Center(
    child: Text('Floating Action Button'),
  ),
  floatingActionButton: FloatingActionButton(
    onPressed: () {
      // ここにアクションを記述
    },
    child: Icon(Icons.add),
  ),
)

FABをBottomNavigationBarに埋め込む方法

FABをBottomNavigationBarに埋め込む方法も簡単です。ScaffoldのbottomNavigationBarプロパティにBottomAppBarウィジェットを設定し、その中にFABを配置します。以下に実例を示します。

Scaffold(
  appBar: AppBar(
    title: Text('FAB in BottomNavigationBar'),
  ),
  body: Center(
    child: Text('FAB in BottomNavigationBar'),
  ),
  floatingActionButton: FloatingActionButton(
    onPressed: () {
      // ここにアクションを記述
    },
    child: Icon(Icons.add),
  ),
  floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
  bottomNavigationBar: BottomAppBar(
    shape: CircularNotchedRectangle(),
    notchMargin: 4.0,
    child: Row(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        IconButton(
          onPressed: () {},
          icon: Icon(Icons.menu),
        ),
        IconButton(
          onPressed: () {},
          icon: Icon(Icons.search),
        ),
      ],
    ),
  ),
)

このコードにより、FABがBottomNavigationBarの中央に埋め込まれ、周囲のアイテムと自然に並ぶようになります(useMaterial3未使用時)。これにより、アプリの主要なアクションをユーザーに目立つように提示できます。

FloatingActionButtonのカスタマイズ

複数のFABを設定する方法

FABを複数設定する場合、Stackウィジェットを使用してFABを重ねます。その後、Positionedウィジェットを使用してFABの位置を調整します。以下に実例を示します。

Scaffold(
  appBar: AppBar(
    title: Text('Multiple FABs'),
  ),
  body: Center(
    child: Text('Multiple Floating Action Buttons'),
  ),
  floatingActionButton: Stack(
    children: [
      Positioned(
        bottom: 20,
        right: 20,
        child: FloatingActionButton(
          onPressed: () {
            // アクションを記述
          },
          child: Icon(Icons.add),
        ),
      ),
      Positioned(
        bottom: 90,
        right: 20,
        child: FloatingActionButton(
          onPressed: () {
            // アクションを記述
          },
          child: Icon(Icons.remove),
        ),
      ),
    ],
  ),
)

FABのサイズ変更方法

FABのサイズを変更するには、miniプロパティを使用します。miniプロパティをtrueに設定すると、FABのサイズが小さくなります。以下に実例を示します。

FloatingActionButton(
  onPressed: () {
    // アクションを記述
  },
  child: Icon(Icons.add),
  mini: true, // FABのサイズを小さくする
)

FABのアイコンとラベルの設定

FABのアイコンは、childプロパティを使用して設定します。通常、Iconウィジェットを使用してアイコンを設定しますが、テキストや他のウィジェットも設定できます。backgroundColorプロパティでFABの背景色を変更することもできます。

FloatingActionButton(
  onPressed: () {
    // アクションを記述
  },
  child: Icon(Icons.add),
  backgroundColor: Colors.red,
)

FABのアクションとイベント処理

FABを押したときのアクションは、onPressedプロパティに関数を設定することで実装できます。以下の例では、FABを押すとSnackBarが表示されます。

Scaffold(
  appBar: AppBar(
    title: Text('FAB Action Example'),
  ),
  body: Center(
    child: Text('Floating Action Button Action Example'),
  ),
  floatingActionButton: FloatingActionButton(
    onPressed: () {
      // FABを押したときのアクション
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('FAB pressed!'),
        ),
      );
    },
    child: Icon(Icons.add),
  ),
)

このように、FABを使用してアプリケーションの主要なアクションを簡単に実装できます。カスタマイズやイベント処理を通じて、FABはアプリケーションのユーザビリティを向上させる重要な要素です。

アイコンとラベルの追加

FloatingActionButton.extendedを使ってアイコンとラベルを持つFloatingActionButtonを簡単に作成することができます。

FloatingActionButton.extended(
  onPressed: () {},
  label: Text('Add'),
  icon: Icon(Icons.add),
)

このコードでは、onPressedにタップ時のアクションを追加し、labelにテキストラベルを指定し、iconにアイコンを設定しています。FloatingActionButton.extendedを使用することで、短いコードで簡単にアイコンとラベルを追加することができます。

FABのベストプラクティス

FABのデザインガイドライン

GoogleのMaterial Designガイドラインによれば、FABを効果的に使用するには、FABは主要なアクションを強調するためのボタンであり、画面上に1つだけ表示すべきです。また、FABは通常、画面の右下隅に配置されることが推奨されています。

FABのアクセシビリティ対応

FABを利用する際には、アクセシビリティに配慮することが重要です。以下の点に注意してください。

  • 適切なコントラスト比
    FABの背景色とアイコンの色のコントラスト比を十分に高く保ち、視覚障害のあるユーザーにもわかりやすくすることが求められます。
  • 適切なサイズ
    FABのサイズは、タップしやすいように十分な大きさが必要です。Googleのガイドラインでは、FABのサイズは56x56dp(標準サイズ)が推奨されています。
  • ラベルの追加
    FABにはテキストラベルを追加して、ボタンの目的を明確にすることが推奨されています。これにより、スクリーンリーダーを使用しているユーザーにもFABの機能が伝わります。

Q&A

Q1: FABをBottomNavigationBarに埋め込む方法は何ですか?

A1: FABをBottomNavigationBarに埋め込むには、BottomAppBarウィジェットを使用し、notchプロパティを設定して、FABが収まるようにします。floatingActionButtonプロパティにFABを追加し、floatingActionButtonLocationプロパティをFloatingActionButtonLocation.centerDockedに設定することで、FABがBottomNavigationBarに埋め込まれた状態で表示されます。

Q2: FABにアイコンとラベルをどのように設定しますか?

A2: FABにアイコンを設定するには、FloatingActionButtonウィジェットのchildプロパティにIconウィジェットを使用します。アイコンの種類はIconsクラスから選択できます。ラベルを設定するには、Tooltipプロパティにテキストを追加することで、FABにマウスオーバーした際にラベルが表示されるようになります。

Q3: FABのアクセシビリティ対応にはどのようなポイントがありますか?

A3: FABのアクセシビリティ対応には以下のポイントがあります。

  • FABの背景色とアイコンの色のコントラスト比を十分に高く保つことで、視覚障害のあるユーザーにもわかりやすくします。
  • FABにテキストラベルを追加して、ボタンの目的を明確にすることが推奨されています。
  • FABに適切なTooltipを設定し、スクリーンリーダーでボタンの目的が読み上げられるようにすることが重要です。

まとめ

FloatingActionButton(FAB)は、Flutterアプリケーションにおいて主要なアクションを強調するために使用されるボタンです。FABの効果的な使用法やカスタマイズ方法について学ぶことで、アプリケーションのユーザビリティを向上させることができます。

FABの追加やカスタマイズに関しては、複数のFABを設定する方法、FABのサイズ変更方法、FABを複数並べる方法があります。また、FABの実装例では、アイコンやツールチップの設定、アクションやイベント処理が重要です。

特に重要な部分を箇条書きでまとめます。

  • FABは画面上に1つだけ表示すべきで、主要なアクションを強調するために使用されます。
  • FABは通常、画面の右下隅に配置されることが推奨されています。
  • FABの背景色とアイコンの色のコントラスト比を十分に高く保ち、視覚障害のあるユーザーにもわかりやすくすることが重要です。
  • FABの効果的な利用法やベストプラクティスを理解し、実践することで、アプリケーションのユーザビリティやアクセシビリティを向上させることができます。これにより、ユーザーにとって快適なアプリケーション体験を提供することが可能になります。

参考

全ソース

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final userMaterial3 = false;
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: userMaterial3 ? null : Colors.blue,
        colorSchemeSeed: userMaterial3 ? Colors.blue : null,
        useMaterial3: userMaterial3,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('FAB in BottomNavigationBar'),
      ),
      body: Center(
        child: Text('FAB in BottomNavigationBar'),
      ),
/*      floatingActionButton: FloatingActionButton(
        mini: true,
        tooltip: 'show snack bar',
        onPressed: () {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Text('FAB pressed!'),
            ),
          );
        },
        child: Icon(Icons.add),
      ),*/
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () {},
        label: Text('Add'),
        icon: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      bottomNavigationBar: BottomAppBar(
        shape: CircularNotchedRectangle(),
        notchMargin: 4.0,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            IconButton(
              onPressed: () {},
              icon: Icon(Icons.menu),
            ),
            IconButton(
              onPressed: () {},
              icon: Icon(Icons.search),
            ),
          ],
        ),
      ),
    );
  }
}