Flutterは、Googleによって開発されたオープンソースのモバイルアプリケーション開発フレームワークです。Flutterを使用すると、簡単に美しく、高機能なモバイルアプリケーションを作成することができます。Flutterには、FloatingActionButton(以下、FAB)と呼ばれる、画面上に浮かび上がる円形のアクションボタンがあります。FABは、アプリケーションの操作性を高め、ユーザーにより簡単なナビゲーションを提供することができます。この記事では、FlutterのFABの使い方を説明します。
FloatingActionButtonの基本的な使い方
FlutterのFloatingActionButtonは、MaterialDesignの仕様に従って作られています。以下のように、Scaffoldウィジェットの中にFABを配置することで、基本的なFABの実装が可能です。
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My App'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),
body: Center(
child: Text('Hello, World!'),
),
);
}
}
上記の例では、ScaffoldウィジェットのfloatingActionButtonプロパティにFABを配置しています。FABには、onPressedコールバック、child、およびbackgroundColorなどのプロパティが含まれています。onPressedコールバックは、FABが押されたときに実行される関数を指定します。childは、FABに表示されるアイコンを指定します。backgroundColorは、FABの背景色を指定します。
FloatingActionButtonの位置
FlutterのFABは、画面の右下隅にデフォルトで配置されますが、任意の位置に配置することができます。FABの位置を変更するには、floatingActionButtonLocationプロパティを使用します。例えば、以下のように、左下に配置する場合は、FloatingActionButtonLocation.startFloatを使用します。サンプルコードは以下のとおりです。(上記サンプルコードのScaffoldウィジット内の関連部分のみ抜粋して記載します)
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
backgroundColor: Colors.green,
),
floatingActionButtonLocation: FloatingActionButtonLocation.startFloat,
FloatingActionButtonの拡張
FlutterのFABは、アイコンだけでなく、拡張されたメニューや複数のFABを配置することもできます。以下の例では、複数のFABを配置し、各FABが押されたときに異なるアクションを実行する方法を示します。
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: () {
// FAB 1を押したときに行いたい処理
},
child: Icon(Icons.add),
backgroundColor: Colors.blue,
),
SizedBox(
height: 10,
),
FloatingActionButton(
onPressed: () {
// FAB 2を押したときに行いたい処理
},
child: Icon(Icons.edit),
backgroundColor: Colors.red,
),
],
),
上記の例では、2つのFABをColumnウィジェット内に配置し、それぞれが異なるアクションを実行するようにしています。また、SizedBoxを使用して、2つのFABの間に間隔を設定しています。
ボタンを押下したら別のFloatingActionButtonが表示される
上記のように常に複数のFloatingActionButtonを表示することもできますが、画面表示範囲が限られているモバイルデバイスでは、必要な時だけ、FloatingActionButtonを表示することもできます。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with TickerProviderStateMixin {
bool _isExpanded = false;
late AnimationController _animationController;
late Animation<double> _animation;
@override
void initState() {
super.initState();
_animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 300),
);
_animation = CurvedAnimation(
parent: _animationController,
curve: Curves.easeInOut,
);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
void _toggleExpand() {
setState(() {
_isExpanded = !_isExpanded;
_isExpanded
? _animationController.forward()
: _animationController.reverse();
});
}
void _closeExpand() {
if (_isExpanded) {
setState(() {
_isExpanded = false;
_animationController.reverse();
});
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: GestureDetector(
onTap: _closeExpand,
child: Scaffold(
appBar: AppBar(
title: Text('FloatingActionButton Demo'),
),
body: Center(
child: Text('Press the button below'),
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: _toggleExpand,
child: AnimatedSwitcher(
duration: Duration(milliseconds: 300),
transitionBuilder: (child, animation) => ScaleTransition(
scale: animation,
child: child,
),
child: _isExpanded ? Icon(Icons.close) : Icon(Icons.add),
),
),
if (_isExpanded)
ScaleTransition(
scale: _animation,
child: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.favorite),
),
),
if (_isExpanded)
ScaleTransition(
scale: _animation,
child: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.share),
),
),
if (_isExpanded)
ScaleTransition(
scale: _animation,
child: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.star),
),
),
],
),
),
),
);
}
}
_isExpanded
というブール型の状態を使って、最初は3つのFloatingActionButtonが非表示になっています。最初のFloatingActionButtonを押すと、 _isExpanded
の値が切り替わり、3つのFloatingActionButtonが表示されます。それぞれの追加のFloatingActionButtonは、if
文を使って、 _isExpanded
の値に基づいて表示/非表示を切り替えます。
また、AnimatedSwitcher
とScaleTransition
を使用して、アイコンのアニメーションを追加しています。AnimatedSwitcher
は、アイコンが切り替わる際にアニメーションを提供します。ScaleTransition
は、各ボタンがアニメーションで表示されるようにするために使用されます。また、AnimationController
とCurvedAnimation
を使用して、ボタンが拡大縮小するアニメーションを作成しました。_toggleExpand
関数がFloatingActionButton
のonPressed
に割り当てられ、ボタンが押されるたびに _isExpanded
とアニメーションの状態が切り替わります。
さらに、GestureDetector
を使用して、ユーザーが画面外をタップすると_closeExpand
関数が呼び出され、_isExpanded
がfalse
に設定され、アニメーションが逆方向に再生されます。これにより、ユーザーがボタン以外の場所をタップした場合でも、拡張されたボタンが閉じられます。
まとめ
FlutterのFloatingActionButtonは、ユーザーフレンドリーなアプリケーションを作成する上で、重要な役割を果たします。FABは、基本的にScaffoldウィジェット内に配置され、onPressed、child、backgroundColorなどのプロパティを設定することができます。FABの位置を変更するには、floatingActionButtonLocationプロパティを使用します。また、複数のFABを配置することもできます。FABをうまく活用して、より使いやすく、魅力的なモバイルアプリケーションを作成しましょう。