【Flutter】SpeedDialでアクション選択をスマートに!

対象者

Flutterを使ってアプリ開発をしているけれど、ユーザーインターフェイスにもう一歩踏み込んだ魅力を加えたい、そんなあなたにぴったりの機能がflutter_speed_dialです。この記事では、flutter_speed_dialを使って、アプリにダイナミックで使いやすいフローティングアクションボタンを追加する方法を紹介します。

はじめに

Flutterを使用しているアプリ開発者の皆さん、UIの革新に挑戦したいと思いませんか?もしあなたが、アプリのユーザーインターフェースにもう一歩踏み込んだ魅力を加えたいと考えているなら、flutter_speed_dialがその答えになるかもしれません。この便利なウィジェットを使えば、アプリにダイナミックで使いやすいフローティングアクションボタンを追加できます。

flutter_speed_dialの基本から、より高度なカスタマイズ方法に至るまで、この記事では一歩一歩、わかりやすく解説していきます。flutter_speed_dialの導入方法から始まり、基本的な使い方、さらにはSpeedDialChildのカスタマイズ方法まで、具体的なサンプルコードとともに紹介していきます。

flutter_speed_dialの基本

Flutterのflutter_speed_dialパッケージは、アプリケーションに簡単にアクセスできるボタンを追加するための便利なツールです。このセクションでは、flutter_speed_dialの導入方法、基本的な使い方、および主要なパラメータについて解説します。

flutter_speed_dialの導入方法

flutter_speed_dialをFlutterプロジェクトに導入するには、まずpubspec.yamlファイルにこのパッケージを依存関係として追加する必要があります。以下の手順に従ってください:

  1. pubspec.yamlファイルを開きます。
  2. dependenciesセクションにflutter_speed_dial:とそのバージョンを追記します。
  3. コマンドラインまたはターミナルでflutter pub getを実行し、パッケージをプロジェクトにインストールします。
dependencies:
  flutter_speed_dial: ^最新のバージョン

基本的な使い方

flutter_speed_dialを使用するには、FlutterのFloatingActionButtonの代わりにSpeedDialウィジェットを配置します。SpeedDialウィジェットは、複数のアクションを含むことができ、ユーザーがメインのアクションボタンをタップすると表示されます。

SpeedDial(
  icon: Icons.add,
  activeIcon: Icons.close,
  buttonSize: 56.0, 
  visible: true,
  curve: Curves.bounceIn,
  overlayColor: Colors.black,
  overlayOpacity: 0.5,
  onOpen: () => print('OPENING DIAL'),
  onClose: () => print('DIAL CLOSED'),
  tooltip: 'Speed Dial',
  heroTag: 'speed-dial-hero-tag',
  backgroundColor: Colors.white,
  foregroundColor: Colors.black,
  elevation: 8.0,
  shape: CircleBorder(),
  children: [
    SpeedDialChild(
      child: Icon(Icons.accessibility),
      backgroundColor: Colors.red,
      label: 'First',
      labelStyle: TextStyle(fontSize: 18.0),
      onTap: () => print('FIRST CHILD'),
    ),
    // Add more SpeedDialChildren as needed
  ],
)

パラメータの説明

SpeedDialウィジェットは、多数のパラメータを通じて高度にカスタマイズ可能です。主要なパラメータには以下のものがあります:

  • iconactiveIcon:スピードダイアルが閉じているときと開いているときに表示されるアイコンです。
  • buttonSize:スピードダイアルボタンのサイズを定義します。
  • visible:スピードダイアルが表示されるかどうかを制御します。
  • closeManually:ユーザーが手動でスピードダイアルを閉じる必要があるかどうかを指定します。falseにしておくと、展開したボタンを押すと決定されスピードダイアルが自動で閉じます。trueの場合、自動で閉じず、スピードダイアルを再度押すことで、展開したボタンを閉じます。
  • curve:アニメーションのカーブを定義します。
  • overlayColoroverlayOpacity:スピードダイアルが開いているときに背景に表示されるオーバーレイの色と不透明度です。
  • onOpenonClose:スピードダイアルが開いたり閉じたりするときに実行されるコールバック関数です。
  • backgroundColorforegroundColorelevationshape:スピードダイアルの外観をカスタマイズするためのパラメータです。
  • direction:スピードダイアルが展開される方向を指定します。例えば、SpeedDialDirection.upはボタンが上に展開されることを意味します。これにより、スピードダイアルの配置とユーザーインターフェースのデザインに柔軟性を持たせることができます。
  • switchLabelPosition:このパラメータをtrueに設定すると、アクションボタンのラベルがアイコンの反対側に表示されます。これは、特にスピードダイアルが画面の端にある場合に、ラベルの視認性を向上させるのに役立ちます。

これらのパラメータを適切に設定することで、アプリケーションのブランドやデザインに合わせたスピードダイアルを簡単に作成できます。

SpeedDialChildのカスタマイズ

Flutterのflutter_speed_dialウィジェットにおいて、SpeedDialChildはメインのSpeedDialボタンをタップした際に表示される、個々のアクションボタンをカスタマイズするための要素です。この中項目では、SpeedDialChildの見た目と挙動をカスタマイズする方法を詳しく解説します。カスタマイズ可能なポイントは主に以下の通りです:

アイコンとラベル

  • アイコン: SpeedDialChildにはchildプロパティを使用してアイコンを設定できます。FlutterのIconウィジェットやImageウィジェットを利用して、様々なアイコンを表示させることができます。
  • ラベル: labelプロパティを使うことで、アイコンの下または横にテキストラベルを追加できます。このラベルは、ユーザーにアクションの目的を伝えるのに役立ちます。

色と形

  • 背景色: backgroundColorプロパティを通じて、SpeedDialChildの背景色をカスタマイズできます。アプリのテーマカラーに合わせた色を設定することで、一貫性のあるデザインを実現できます。
  • 形: shapeプロパティを使用して、ボタンの形状をカスタマイズすることが可能です。例えば、CircleBorderRoundedRectangleBorderを指定して、角の丸いボタンや円形のボタンを作成できます。

挙動

  • タップ時のアクション: onTapプロパティを利用して、SpeedDialChildがタップされたときの動作を定義できます。例えば、新しい画面に遷移する、ダイアログを表示する、データを更新するといったアクションを実装できます。
  • 長押し時のアクション: onLongPressプロパティを使って、ボタンが長押しされたときの動作も設定できます。

まとめ

flutter_speed_dialを使って、Flutterアプリに複数のアクションを提供するフローティングアクションボタンを簡単に追加する方法を勉強しました。基本的な導入から、カスタマイズ方法、そしてSpeedDialChildの活用まで、アプリのユーザビリティと魅力を高めるための知識を深めました。この記事で得た学びを活かし、より使いやすく、目を引くアプリ開発に挑戦してください。

参考

ソース(main.dartにコピペして動作確認用)

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

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      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> {
  var _selectedDialog = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('選択された項目: $_selectedDialog'),
            SpeedDial(
              spacing: 5,
              activeIcon: Icons.close,
              icon: Icons.add,
              closeManually: false,
              direction: SpeedDialDirection.down,
              switchLabelPosition: true,
              childrenButtonSize: const Size(64, 76),
              buttonSize: const Size(56.0, 56.0),
              overlayColor: Colors.black,
              overlayOpacity: 0.3,
              visible: true,
              curve: Curves.bounceIn,
              onOpen: () => print('OPENING DIAL'),
              onClose: () => print('DIAL CLOSED'),
              tooltip: 'Speed Dial',
              heroTag: 'speed-dial-hero-tag',
              backgroundColor: Colors.blue,
              foregroundColor: Colors.black,
              elevation: 8.0,
              shape: CircleBorder(),
              children: [
                SpeedDialChild(
                  child: const Icon(Icons.directions_car),
                  backgroundColor: Colors.blue,
                  foregroundColor: Colors.white,
                  labelBackgroundColor: Colors.black,
                  labelStyle: TextStyle(color: Colors.white),
                  shape: CircleBorder(),
                  label: '車',
                  onTap: () => setState(() => _selectedDialog = '車'),
                ),
                SpeedDialChild(
                  child: const Icon(Icons.directions_transit),
                  backgroundColor: Colors.blue,
                  foregroundColor: Colors.white,
                  labelBackgroundColor: Colors.black,
                  labelStyle: TextStyle(color: Colors.white),
                  shape: StadiumBorder(),
                  label: '公共交通',
                  onTap: () => setState(() => _selectedDialog = '公共交通'),
                ),
                SpeedDialChild(
                  child: const Icon(Icons.directions_bike),
                  backgroundColor: Colors.blue,
                  foregroundColor: Colors.white,
                  labelBackgroundColor: Colors.black,
                  labelStyle: TextStyle(color: Colors.white),
                  shape: RoundedRectangleBorder(
                      side: const BorderSide(width: 1.0),
                      borderRadius: BorderRadius.circular(10)),
                  label: '自転車RoundedRectangleBorder)',
                  onTap: () => setState(() => _selectedDialog = '自転車'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

このFlutterサンプルコードでは、flutter_speed_dialを使用して、ユーザーが選択できる複数のアクションを持つフローティングアクションボタンをアプリに追加する方法を示しています。ここでのポイントを箇条書きでまとめます。

  • SpeedDialウィジェットを使用して、複数のアクションを提供するフローティングアクションボタンを配置します。これはアプリのメインアクションボタンをタップすることでアクセスできます。

  • iconactiveIconプロパティを使用して、フローティングアクションボタンのデフォルトアイコンとアクティブ時のアイコンを設定します。

  • closeManuallyプロパティがfalseに設定されているため、ユーザーが子アクションをタップすると、スピードダイアルは自動的に閉じます。

  • directionプロパティにより、スピードダイアルが下方向に展開されます。

  • childrenプロパティ内にSpeedDialChildウィジェットを配置し、各子アクションをカスタマイズします。各子アクションは異なるアイコン、背景色、ラベルを持ち、特定のアクション(例:車、公共交通、自転車)に対応します。

  • onTapコールバックを使用して、各SpeedDialChildがタップされたときの動作を定義します。この例では、選択されたアクションに応じてテキストが更新されます。

  • overlayColoroverlayOpacityを設定することで、スピードダイアルが開かれたときの背景のオーバーレイの見た目をカスタマイズします。

このサンプルコードを通じて、flutter_speed_dialウィジェットを使って、アプリのユーザーインターフェースをダイナミックでユーザーフレンドリーなものにする方法を理解できます。各種設定をカスタマイズすることで、アプリの見た目と機能性をさらに向上させることが可能です。