こんにちはyu_to(@yu_to_python)です。
今回はFlutterでアプリ作る際に必ず使用するWidgetであるScaffoldについて解説していきます。
そもそもWidgetの事について詳しく知らないという方はこちらの記事で詳しく解説しているので参考にしてください。

この記事を最後まで読めばScaffoldの使い方と、よく使うプロパティについて理解できると思うので是非最後まで読んでみてください。
目次
Scaffoldの特徴
UI構築のスタート地点
FlutterのUI構築は様々なWidgetをミルフィーユの様に積み重ねていって構築します。
ScaffoldはそのWidgetミルフィーユの中で最下層(一番最初)で使用されるWidgetです。
(厳密には一番最初は〇〇App系ですがレイアウトに関連するWidgetでははいので割愛)
このScaffoldをスタート地点として、その上に数多の他のWidgetを配置していってUIを構築します。
...
return MaterialApp(
title: 'demo',
home: Scaffold(
// Scaffoldの中に色々なWidgetを指定していく
appBar: AppBar(title: Text('Scaffold')),
body: Center(
child: Text('Scaffold'),
),
),
);
...
例えると「白紙のキャンバス」
Scaffoldの役割を理解する上で分かりやすいのは「白紙のキャンバス」と捉えることだと思います。
そしてその他Widgetは「絵の具」みたいなイメージです。
Scaffoldというキャンバスにボタンやテキスト等のレイヤーをどんどん置いていって進めるのがFlutterでUI構築する際の基礎になります。

サンプルコード
コピペですぐ動かせるのでまずは実際に動かしてみてください。
動作確認したバージョンは下記の通りです。
・Flutter 3.0.1
・Dart 2.13.3
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'demo',
home: Home(),
);
}
}
class Home extends StatefulWidget {
const Home({Key key}) : super(key: key);
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.green[200],
appBar: AppBar(title: Text('Scaffold')),
body: Center(
child: Image.network(
'https://cdn-images-1.medium.com/max/1200/1*ilC2Aqp5sZd1wi0CopD1Hw.png',
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => print('ボタンが押されたよ'),
child: Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}

よく使うプロパティ
Scaffoldには大量のプロパティが実装されていますが、普段開発する上で特に使う頻度が高そうなプロパティをピックアップして解説します。
body
bodyプロパティは画面のメイン部分(画面スクショの白い箇所)に表示したいWidgetを指定します。
例えば、画面中央に画像を表示させたい場合はbodyプロパティにCenter Widgetを指定してその子要素としてImage Widgetを指定することで実現可能です。
...
return Scaffold(
appBar: AppBar(title: Text('Scaffold')),
body: Center(
child: Image.network(
'https://cdn-images-1.medium.com/max/1200/1*ilC2Aqp5sZd1wi0CopD1Hw.png',
),
),
);
...

appBar
基本的にこのappBarプロパティにはその名の通りAppBarというWidgetが指定されるのがほとんどです。
AppBarは俗に言う「ヘッダー」を簡単に作成できるWidgetです。
ヘッダーはその画面に合った情報を表示させたり、ユーザー動作の補助ボタンが設置されていたりとUX向上に直結する重要度の高い要素です。
AppBarについては個別に解説記事を書いていますので良ければこちらを参考にしてみてください。

AppBarプロパティが設定されなければ画面全体がメイン画面になります。
...
return Scaffold(
appBar: AppBar(title: Text('Scaffold')),
);
...

backgroundColor
backgroundColorプロパティはその名の通りメイン画面部分の背景色を指定可能です。
AppBarが無ければ画面全体、あればAppBar以外の箇所の色が変わります。
...
return Scaffold(
backgroundColor: Colors.green[200],
);
...


floatingActionButton
floatingActionButtonプロパティはメイン画面の右下に要素を表示可能です。
基本的にこのfloatingActionButtonプロパティにはその名の通りFloatingActionButtonというWidgetが指定されるのがほとんどです。
画面の右下は多くの人が一番画面タップしやすい位置ですから、その位置に対してデフォルトで要素を表示させられるプロパティが用意されているのはFlutterの親切設計ですね。
...
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () => print('ボタンが押されたよ'),
child: Icon(Icons.add),
),
);
...

tips
floatingActionButtonを好きな場所に置く
floatingActionButtonに関連してfloatingActionButtonLocationというプロパティも用意されていて、これを使うことでデフォルトだと画面右下にしか要素を出せない所を他の位置に表示させることが可能になります。
floatingActionButtonを使っていない状態でfloatingActionButtonLocationを使ってしまってもエラーにはなりませんし画面上は何も変わりません。
例えばFloatingActionButtonLocation.centerFloatを指定するとメイン画面下部に表示できます。
もちろん他にも色々位置を指定可能です。
...
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () => print('ボタンが押されたよ'),
child: Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
...


おわり
今回はScaffoldについて解説してきました。
アプリを開発する上でScaffoldは必ず使うWidgetなのでこの機会にぜひ使い方を覚えてみてください。
今回紹介した仕様以外も、もっと深堀りしたい方は公式ドキュメントを参照してみてください。
このブログでは他にもFlutterに関する記事を上げているので良ければそちらも参考にしてみてください。
質問やご指摘もお待ちしてますー。


