こんにちは。教育系エンジニアのひらまつ(@hiramatsuu)です。
Flutterの連載、第一回目ではFlutterとはどういうものなのか?を解説しましたが、抽象的な話が多くて、いまいちイメージしづらかったかもしれません。
なので第二回目にあたる今回は、Flutterの実際のコードを見ることで、Flutter開発のイメージを具体的に持てるようになっていただきたいと思います。
具体的には、以下のようなテーマをこの記事で学んでいきます。
- UIがDartというプログラミング言語で書かれていること
- Flutterはすべての画面部品がWidgetであること
- Widgetツリーとはなにか?
Flutter開発のコードを見てみよう
まずはFlutter公式チュートリアルにも載っている、以下の非常にシンプルな画面をつくるためのコードを見てみましょう。
左がプログラミング言語「Dart」で書かれたコードで、右がこのコードを書いた場合のFlutterのUI画面です。(右側に何も表示されていない場合は、右上の「▶︎ Run」ボタンを押してください。)
ここで確認していただきたいのは、左のDartコードを書くことで、「Welcome to Flutter」と書かれた青色のAppBarと、「Hello World」というテキストが書かれた、とても単純なFlutterアプリの画面が作成されている、ということです。
Dartの文法は次回以降に詳しく学んでいきますので、このコードの詳しい意味はまだわからなくてOKです。
ここでは、特に注目していただきたいポイントについて、いくつか見ていきましょう。
UIがマークアップ言語ではなくプログラミング言語で書かれている
このコードはUI画面を実装しているものなのですが、これは「Dart」というプログラミング言語で書かれています。
通常のアプリ開発であれば、HTMLやXMLなどのマークアップ言語でUIを記述しますが、FlutterではDartというプログラミング言語でUIを記述します。
その証拠に、コードをよく見てみると3行目に「main関数」、5行目には「MyAppクラス」があります。関数やクラスは、マークアップ言語にはない概念です。(クラスはHTMLにもありますが、プログラミング言語のクラスとは別のものです)。
このように、Flutterでは見た目の部分(フロントエンド)も、目に見えない裏側の部分(バックエンド)も、Dartというプログラミング言語だけで開発できるようになっています。
第一回目でも書きましたが、フロントエンドもバックエンドも共通のプログラミング言語で開発できるのはとても大きなメリットです。
この特徴が、Flutterで生産性の高い開発ができる理由のひとつになっています。
画面部品やレイアウトはすべてWidgetで表現されている
FlutterのUI画面では、すべての画面部品やレイアウトはWidget(ウィジェット)で表現されています。
Widgetとは何かというと、Widgetクラスを継承しているクラス(Widgetクラスのサブクラス)のことです。Widgetごとにそれぞれ、Flutterアプリの画面を形づくるための機能を持っています。
Widgetの例としては、以下のようなものがあります。
- MaterialAppクラス:マテリアルデザインのためのWidget
- Scaffoldクラス:マテリアルデザインのためのWidget
- AppBarクラス:マテリアルデザインのAppBarを作るためのWidget
- Centerクラス:中央揃えのためのWidget
- Textクラス:テキストを表示するためのWidget
マテリアルデザインとは、Googleが提唱しているデザインのガイドラインのことです。Androidのアプリの多くはマテリアルデザインで作成されています。
これらのWidgetの意味を知った上で、もう一度上記のコードを見てみましょう。
「Welcome to Flutter」と書かれたAppBar(11~13行目)や、「Hello World」という中央揃えのテキスト(14~16行目)の、Dartコードとの対応が直感的にも理解できると思います。
Flutterにおいてはこのように、画面の構成に関するすべての機能がWidgetとして表現されています。こういった様々な機能を持つWidgetを組み合わせることで、画面を作成していきます。
Widgetの中にWidgetがあるという入れ子の構造になっている
さらにコードをよく見てみると、Widgetの中にWidgetがあるという構造になっているのがわかると思います。
どういうことかと言うと、上述のコードを見ると以下のような構成になっていると思います。
- MyAppクラスの、buildメソッドの戻り値にMaterialAppクラス
- MaterialAppクラスの、homeプロパティにScaffoldクラス
- Scaffoldクラスの、appBarプロパティにAppBarクラス、bodyプロパティにCenterクラス
- AppBarクラスの、titleプロパティにTextクラス
- Centerクラスの、childプロパティにTextクラス
つまり、Widgetのクラスの中に、また別のクラスが書かれているという構造になっています。
このようにFlutterでは、Widgetの中にWidgetがあるという、Widgetの入れ子の構造によって画面を作成します。上述のコードを図にすると以下のようになります。

こういった構造をWidget Tree(ウィジェットツリー)と言います。一番上のMyAppクラスを根元にした、木(Tree)構造になっているためです。
Widgetツリーは言うなれば、UI画面の設計図です。Flutterでは、Widgetツリーの情報をもとにUI画面が描画されます。
UI画面にボタンを追加してみよう
なので、UI画面に何らかの要素を追加したいときには、このWidgetツリーにWidgetを追加する必要があります。
例えば、Floating Action Buttonを追加するには以下のように書きます。
「▶︎ Run」ボタンを押すと、青丸に「+」のマークが付いたボタンが新しく表示されているのがわかると思います。このボタンが「Floating Action Button」という、マテリアルデザインにおいて主要な操作を行うためのボタンです。
コードをどう編集したのかというと、17~20行目の部分です。
ScaffoldクラスのfloatingActionButtonプロパティに、FloatingActionButtonクラスを指定しています。また、FloatingActionButtonクラスのchildプロパティには、Iconクラスが指定されています。
変更したコードのWidgetツリーは以下のようになっています。

Widget名からも明らかですが、ここで追加したWIdgetはそれぞれ以下のような機能です。
- FloatingActionButtonクラス:FloatingActionButtonを表現するWidget
- Iconクラス:アイコンを表現するWidget(今回は「+」のアイコン)
このように、Flutterにおいて画面部品を追加したければ、追加したい部品に対応するWidgetをWidgetツリーに追加します。
「画面部品を追加したければ、そのWidgetをツリーに追加すれば良い」というのは非常に直感的でわかりやすいですよね。
こういった仕様によって、誰でも簡単にUI画面を作成することを可能にしています。実際のところ、いくつかのWidgetの役割とプロパティを覚えてしまえば、簡単なアプリは短時間で作れてしまいます。
おわりに:Everything is a Widget
本記事では以下のことを学びました。
- UIがDartというプログラミング言語で書かれていること
- Flutterはすべての画面部品がWidgetであること
- Widgetツリーとはなにか?
Flutterは“everything is a widget(すべてはウィジェット)”というスローガンを掲げていますが、その意味とメリットがよく理解できたのではないでしょうか。
これが実際のFlutterのコードでした。実際のコードを見ることで、よりFlutter開発のイメージがしやすくなっていれば幸いです。
そしてここでも見たように、Flutterはプログラミング言語「Dart」で書かれているので、開発するにはDartを習得する必要があります。
ですので、次回からはDartの基本的な書き方について学んでいきましょう!