🐕

FlutterのAppBarを本気で学ぶ

2021/10/09に公開

この記事について

本気で学ぶシリーズ第1弾です。公式ドキュメントを参考に、初学者から中級者に向けてわかりやすく解説出来ればと思います。指摘事項や助言などは歓迎です。もしございましたら、Twitterもしくは記事コメントまでお願い致します。

AppBarの基礎

ご存じの通り、FlutterのAppBarはMaterialDesignを元に構成されています。詳しいデザインなどは以下の公式HPを参考にしてください。
https://material.io/components/app-bars-top

まず初めに、AppBarは基本的にScaffoldのappBarプロパティに配置され使用されます。
AppBarの基本的な構成は以下の通りです。leadingやtitleなどの説明は後述するAppBarのプロパティをお読みください。

また、ScaffoldのappBarプロパティは必須では無く、appBarが必要ないアプリもしくは画面の場合は削除する事が可能です。

AppBarのプロパティ

AppBarウィジェットにはactionsなどの一般的なプロパティを含めて、25個のプロパティが存在します。(inherited系統のプロパティは除く)
それらの中でも、よく使われるプロパティを解説していきます。

prop名 説明
leading AppBarタイトルの先頭にwidgetを配置します。通常はアイコンを配置する事が多いですが、Textや画像なども配置する事が出来ます。
automaticallyImplyLeading プロパティ名の通り、leadingを自働的に推測してくれます。具体的には、leadingを設定していない場合で、画面遷移をした時には戻る矢印をleadingに設定してくれたり、drawerを使用した場合は、自働的にハンバーガーメニューを設置するなどの動作を行います。defaultでは適応(true)になっています。
title 言うまでも無い項目ですが、titleに関連したプロパティがいくつか存在します。
centerTitle trueに設定するとタイトルを中央に配置します。defaultではnullです。
titleSpacing 水平方向のTitle余白を設定し調整出来ます。nullの場合はappBarThemeのtitleSpacingが使用されますが、それもnullの場合はNavigationToolbar.kMiddleSpacingが用いられます。これは定数で16.0が初期代入されています。
actions titleWidgetの後の列に、widgetを配置できます。アイコンボタンを設置する事が多いです。
elevation Appbarの境界線(影)を設定します。defaultは4.0で、0.0を設定するとbodyとAppbarの境界線が無くなります。
shadowColor Appbarの境界線(影)の色を設定します。
backgroundColor AppBarの背景色を決定します。
foregroundColor AppBar内の全てのテキストやアイコンの色を決定します。
shape AppBarを丸くしたりする事が出来ます。RoundedRectangleBorderウィジェットやStadiumBorderウィジェットを配置する事が多いです。
flexibleSpace AppBarの背景にImageを設定したり、bottomと組み合わせて、TabBarのみのAppbarを作成したりなど汎用性が非常に高いです。
toolbarHeight Appbarの高さを設定出来ます。

全部盛りサンプル

デザインはともかくとして、上記に述べたプロパティを全て使ったAppBarです。

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

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

  static const String _title = 'Flutter Code Sample';

  
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      title: _title,
      home: MyStatelessWidget(),
    );
  }
}

class MyStatelessWidget extends StatelessWidget {
  const MyStatelessWidget({Key? key}) : super(key: key);
  
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: const Icon(Icons.location_on),
        automaticallyImplyLeading: false,
        title: const Text('AppBar Demo'),
        centerTitle: true,
        titleSpacing: 0.0,
        actions: <Widget>[
          IconButton(
            icon: const Icon(Icons.add_alert),
            tooltip: 'Show Snackbar',
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('This is a snackbar')));
            },
          ),
          IconButton(
            icon: const Icon(Icons.navigate_next),
            tooltip: 'Go to the next page',
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('This is a snackbar')));
            },
          ),
        ],
        elevation: 10.0,
        shadowColor: Colors.blue,
        backgroundColor: Colors.green,
        foregroundColor: Colors.red,
        shape: const StadiumBorder(),
        flexibleSpace: Image.network('https://picsum.photos/200/100'),
        toolbarHeight: 100,
        
      ),
      body: const Center(
        child: Text(
          'Body',
          style: TextStyle(fontSize: 24),
        ),
      ),
    );
  }
}

Tips

よくある質問としてまとめます。要望やアイデアなどがあれば、ぜひご連絡ください。


AppBarの高さを取得したい。⇒

// 下記のAppBarを作成したと仮定して
AppBar appBar = AppBar(title: Text('sample'));
var appBarHeight = appBar.preferredSize.height;
発展と定義

preferredSizeは

Size.fromHeight(toolbarHeight ?? kToolbarHeight + (bottom?.preferredSize.height ?? 0.0));

で定義されています。
toolbarHeightはAppBarのプロパティで設定できますがデフォの値はkToolbarHeightです。
kToolbarHeightは、ToolBarコンポーネントの高さの定数で56.0が初期値で代入されています。


AppBarを透過させたいけど、backgroundColorを設定しても変化しない。⇒

ScaffoldプロパティのextendBodyBehindAppBarをtrueに設定しましょう。

Scaffold(
      extendBodyBehindAppBar: true,
      appBar: AppBar(
        title: Text("test"),
        backgroundColor: Colors.white.withOpacity(0.5),
      ),
      body: ...

余談(BottomAppBarについて)

あまり知られていませんが、Flutterは画面上だけで無く画面下にもAppBarを配置する事が出来ます。解説は避けますが、公式DocのURLと、その画像のみ添付しておきます。
https://api.flutter.dev/flutter/material/BottomAppBar-class.html

最後に

ありがとうございました。
感想やご要望などはTwitterまで連絡いただければ幸いです。感想だけでも喜びます、よろしくお願い致します。
https://twitter.com/urasan_edu

Discussion