[Widget]AppBarを別のWidgetに切り出す方法

動作環境: Flutter 2.8.1 Dart 2.15.1
LINEでこのページを共有するTwitterでこのページを共有するこのページをはてなブックマークに追加

ScaffoldappBar:で指定するAppBarを他のコンポーネントとして切り出そうとして普通のStatelessWidgetとして作ったものを配置すると、以下のようなメッセージが出てきてビルドができません。

エラー文中のOriginalAppBarはこの記事で定義したコンポーネントです。

A value of type 'OriginalAppBar' can't be assigned to a parameter of type 'PreferredSizeWidget?' in a const constructor

この解消方法を紹介したいと思います。
まずはコード全体を掲載します。

lib/main.dart
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) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const Scaffold(
appBar: OriginalAppBar(),
body: Center(
child: Text('AppBarを別クラスに切り出すサンプル'),
),
));
}
}
class OriginalAppBar extends StatelessWidget with PreferredSizeWidget {
const OriginalAppBar({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return AppBar(
title: Text(
'これはオリジナルAppBarです',
style: TextStyle(
color: Colors.grey.shade900,
),
),
backgroundColor: const Color(0xFFF9A825),
centerTitle: true,
);
}
@override
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
}

ポイントは二つあります。
StatelessWidgetを継承するときにwith PreferredSizeWidgetを指定することと、preferredSizeのゲッターをオーバーライドすることです。

ひとつひとつ見ていきましょう。
以下のコードを見てください。

lib/main.dart
class OriginalAppBar extends StatelessWidget with PreferredSizeWidget {
const OriginalAppBar({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {

27行目でOriginalAppBarのクラス定義が始まります。
ここでStatelessWidgetを継承するときにwith PreferredSizeWidgetも指定します。

これはAppBarクラス自体でも同様にPreferredSizeWidgetwithでMixinしていて、ScaffoldAppBarに該当するWidgetを受け取るには必須の設定になります。

そして、PreferredSizeWidgetを読み込んだことで次の設定も必要になります。
コードを見ていきましょう。

lib/main.dart
@override
Size get preferredSize => const Size.fromHeight(kToolbarHeight);

preferredSizeのゲッターを設定する必要があります。
お好みの高さを指定すればよいですが、デフォルトの高さを利用してしまうのがよさそうです。

kToolbarHeightはFlutterに最初から組み込まれている定数で、AppBarのデフォルトの高さになります。
これでAppBarを別のコンポーネントとして切り出すことができました。

定義部分を抜粋するとこんな感じです。

flutter/2.8.1/flutter/packages/flutter/lib/src/material/constants.dart
/// The height of the toolbar component of the [AppBar].
const double kToolbarHeight = 56.0;
/// The height of the bottom navigation bar.
const double kBottomNavigationBarHeight = 56.0;
/// The height of a tab bar containing text.
const double kTextTabBarHeight = kMinInteractiveDimension;

AppBarは比較的小さめのWidgetですが、アプリを作り込んでいくとコード量がだいぶ多くなってくると思います。
別のファイルに切り出して管理できるとコードがメンテしやすくなります。
AppBarを別のWidgetとして切り出す方法