✉️

【Flutter】FloatingActionButtonのサイズ(normal/extended) をいい感じに切り替える

2021/07/11に公開

デモ・コード

タイトルに若干語弊がありますが、FloatingActionButton.extendedのサイズを通常時に近い形にする・元に戻すという実装になっています。

GmailのFABがこんな感じになっています

参考サイト

こちらの回答をほぼそのまま使いました。(他の方法ではうまくいきませんでした)

https://stackoverflow.com/a/64315519

改善点

そのままだと通常時のFABが円形ではなくなってしまっている(若干横長になってしまっている)が、現状の解決策は以下の2点。

  • SizedBoxでラップして、heightwidthに合わせる
  • Iconsizeを小さくして、widthheightに合わせる

SizedBoxでラップして、heightwidthに合わせる

FloatingActionButton.extendedのコードを見てみると、以下のようにlabelの左右に20pxのスペースが設けられていることがわかった。

紛らわしいが、今回はFloatingActionButton.extendediconプロパティは使用せずlabelに直接Iconを指定しているので、icon == nullは常に真となる。

floating_action_button.dart
       child = _ChildOverflowBox(
         child: Row(
           mainAxisSize: MainAxisSize.min,
           children: icon == null
             ? <Widget>[
                 const SizedBox(width: 20.0),  // <= スペース
                 label,
                 const SizedBox(width: 20.0),  // <= スペース
               ]
             : !isExtended ? <Widget>[ 
               const SizedBox(width: 20.0),
               icon,
               const SizedBox(width: 20.0),
           ] : <Widget>[
                 const SizedBox(width: 16.0),
                 icon,
                 const SizedBox(width: 8.0),
                 label,
                 const SizedBox(width: 20.0),
               ],
         ),
       ),

Iconのデフォルトサイズは24なので横幅は20+24+20=64であることがわかり、FloatingActionButton.extendedSizedBoxでラップしheight64に指定することで通常のFABのように円として表示することができる。

  Widget _buildFabWithAnimation() {
    return SizedBox(
      height: 64,
      child: FloatingActionButton.extended(
        onPressed: () {},
        label: AnimatedSwitcher(
	~~
Iconサイズ

https://api.flutter.dev/flutter/widgets/Icon/size.html

Iconのサイズを小さくする

FloatingActionButton.extendedheight48に設定されているので、Iconのサイズを8にすれば通常のFABのように円として表示することができる。
しかし、それだとIconが見づらくなってしまうので基本的には上の方法のほうが良さそう。

また、上記の方法と組み合わせることでFABのデフォルトサイズである56pxで表示することもできる。

floating_action_button.dart
const BoxConstraints _kExtendedSizeConstraints = BoxConstraints(
  minHeight: 48.0,
  maxHeight: 48.0,
);

修正版

Discussion