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ですが、アプリを作り込んでいくとコード量がだいぶ多くなってくると思います。
別のファイルに切り出して管理できるとコードがメンテしやすくなります。