ScaffoldのappBar:で指定するAppBarを他のコンポーネントとして切り出そうとして普通のStatelessWidgetとして作ったものを配置すると、以下のようなメッセージが出てきてビルドができません。
エラー文中のOriginalAppBarはこの記事で定義したコンポーネントです。
A value of type 'OriginalAppBar' can't be assigned to a parameter of type 'PreferredSizeWidget?' in a const constructorこの解消方法を紹介したいと思います。
まずはコード全体を掲載します。
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のゲッターをオーバーライドすることです。
ひとつひとつ見ていきましょう。
以下のコードを見てください。
class OriginalAppBar extends StatelessWidget with PreferredSizeWidget { const OriginalAppBar({Key? key}) : super(key: key); @override Widget build(BuildContext context) {27行目でOriginalAppBarのクラス定義が始まります。
ここでStatelessWidgetを継承するときにwith PreferredSizeWidgetも指定します。
これはAppBarクラス自体でも同様にPreferredSizeWidgetをwithでMixinしていて、ScaffoldがAppBarに該当するWidgetを受け取るには必須の設定になります。
そして、PreferredSizeWidgetを読み込んだことで次の設定も必要になります。
コードを見ていきましょう。
@override Size get preferredSize => const Size.fromHeight(kToolbarHeight);preferredSizeのゲッターを設定する必要があります。
お好みの高さを指定すればよいですが、デフォルトの高さを利用してしまうのがよさそうです。kToolbarHeightはFlutterに最初から組み込まれている定数で、AppBarのデフォルトの高さになります。
これでAppBarを別のコンポーネントとして切り出すことができました。
定義部分を抜粋するとこんな感じです。
/// 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ですが、アプリを作り込んでいくとコード量がだいぶ多くなってくると思います。
別のファイルに切り出して管理できるとコードがメンテしやすくなります。