AppBarをコンポーネント化して全画面に同じデザインを反映させる
今回は、FlutterでAppBarをコンポーネント化する方法を紹介します。
AppBarは多くのアプリでよく使われているWidgetです。
普段利用しているアプリ、ほぼ全ての画面にはAppBarが存在します。
AppBarはほとんど同じデザインで全画面に反映されることが多いですが、
今回はそのAppBarを実際にコンポーネント化する方法について解説します。
✅今回の内容
- 今回使用するプログラム
- AppBarをコンポーネント化する
- 実際に動かしてみる
✅メイン内容
🛠 今回使用するプログラム
1. 元となるプログラム
今回は、AppBar
をコンポーネント化します。
AppBar
をコンポーネント化するケースは様々ですが、
全てのページのAppBar
を同じデザインにするときによくコンポーネント化されます。
なので、今回は画面を2枚用意して、AppBar
をコンポーネント化し、
同じデザインのAppBar
を設置していきたいと思います。
コピペで使えるプログラム
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
"遷移前ページ",
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => TransitionWidget()));
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
class TransitionWidget extends StatelessWidget {
const TransitionWidget({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
"画面遷移",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 23,
),
),
),
body: Center(child: Text("遷移先ページ")),
);
}
}
🛠 AppBarをコンポーネント化する
1. AppBarを作成
まず、AppBar
だけのWidgetを作成します。
class AppBarComponentWidget extends StatelessWidget {
AppBarComponentWidget({required this.title, super.key});
String title;
Widget build(BuildContext context) {
return AppBar(
title: Text(
title,
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 23,
),
),
flexibleSpace: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(colors: [
Colors.blue,
Colors.red,
]),
),
),
);
}
}
このクラスはコンストラクタが呼ばれた時にAppBar
を返却します。
引数にタイトルを設定している理由は、今回AppBar
をコンポーネント化するので表示するページによってタイトルを変えようと思ったからです。
AppBarComponentWidget({required this.title, super.key});
String title;
2. 埋め込んでみる
元となるプログラムのAppBarに上記で作成したAppBarComponentWidgetを当てはめる。
appBar: AppBar(
title: Text(widget.title),
),
//↓変更後
appBar: AppBarComponentWidget(
title: "遷移前ページ",
),
すると、以下のようなエラーが出ます。
The named parameter 'title' is required, but there's no corresponding argument.
Try adding the required argument.dartmissing_required_argument
The argument type 'AppBarComponentWidget' can't be assigned to the parameter type 'PreferredSizeWidget?'.dartargument_type_not_assignable
このエラーが発生する理由ですが、
Scaffold
のappbar
パラメータはPreferredSizeWidget型です。
実は、よく使うAppBar
はPreferredSizeWidget
を実装したクラスです。
なので、AppBar
をコンポーネント化しよう思ったら、そのコンポーネント化したクラスでPreferredSizeWidget
クラスを実装する必要があります。
実装しちゃいましょう。
class AppBarComponentWidget extends StatelessWidget
implements PreferredSizeWidget {
すると、今度はAppBarComponentWidget
にエラーが出ます。
今実装したPreferredSizeWidget
クラスは抽象クラスです。なので、実装したサブクラスでPreferredSizeWidget
クラスの内容をオーバーライドする必要があります。
オーバーライドする内容は下記。
class PreferredSize extends StatelessWidget implements PreferredSizeWidget {
/// Creates a widget that has a preferred size that the parent can query.
const PreferredSize({
super.key,
required this.child,
required this.preferredSize,
});
/// The widget below this widget in the tree.
///
/// {@macro flutter.widgets.ProxyWidget.child}
final Widget child;
//ここ!!
final Size preferredSize;
Widget build(BuildContext context) => child;
}
build
メソッド等はすでにオーバーライドされているので、
今回はpreferredSize
をオーバーライドすれば良いです。
Size get preferredSize {
return Size(double.infinity, 60.0);
}
preferredSize
では、AppBar
のサイズを指定してあげる必要があります。
通常、AppBar
では高さ:56.0が設定されています。
今回は、キリよく60に設定しました。
これで、build
してみると
と、AppBarがMyHomePage
クラスに反映されています。
遷移先のTransitionWidget
クラスにもコンポーネント化したAppBarComponentWidget
クラスを入れましょう。
class TransitionWidget extends StatelessWidget {
const TransitionWidget({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBarComponentWidget(
title: "遷移先ページ",
),
body: Center(child: Text("遷移先ページ")),
);
}
}
🛠 実際に動かしてみる
1. 完成版
これでAppBarのコンポーネント化が完成です。🍎
✅まとめ
今回は、AppBarのコンポーネント化について解説しました。
AppBarをコンポーネント化しようとした時、エラーが出て焦ってしまう時があると思います。
上記の方法で改善できますので、ぜひご参考にしてみてください。
iOSアプリのTestFlightの登録方法については以下の記事で解説しています。
今回はここまで
Discussion