l

o

a

d

i

n

g

.

.

.

短期にFlutterを学習するブログ STEP3:Widgetの基本とUI構築

2026/02/22

Flutter プログラミング 学習

t f B! P L
eyecatch Flutterを触っていて、ここで印象がガラッと変わる人が多いのがこのSTEPです。 環境構築やDartの理解までは、「まあ普通の準備だな」という感覚でしたが、 UIを書き始めると、Flutterがなぜ評価されているのかが一気に腑に落ちます。 特に、WebエンジニアとしてCSSに散々悩まされてきた人ほど、「これは確かに楽だな」と感じるはずです。 そして、FlutterのUIはなぜCSSより楽なのかを理解することができるでしょう。

Widget = View + ロジックという考え方

FlutterのUIは、すべてWidgetで構成されます。 この時点で重要なのは、Widgetを「ただの見た目」と思わないことです。 Widgetは、 画面表示の単位であり、その表示に必要なロジックを含む単位でもあります。 HTML+CSS+JavaScriptのように、ファイルや役割が分散する構造ではありません。 UIに関する責務が、1つのWidgetにまとまっています。 この考え方に慣れると、 「この画面は何をしているのか」 「どこを修正すれば影響が出るのか」 が、コードから直感的に分かるようになります。

StatelessWidget / StatefulWidget

最初に必ず出てくるのが、この2つ。 名前だけ見ると難しそうですが、役割はとても単純です。 StatelessWidgetは、状態を持たないWidget。 与えられたデータを元に、同じ見た目を描画し続けます。 StatefulWidgetは、状態を持つWidgetです。 ボタンを押した、入力が変わった、といった変化に応じて、画面の見た目が変わります。 ここで大事なのは、「どちらを使うかで悩みすぎない」こと。 最初は、 「変わらないなら Stateless」 「変わるなら Stateful」 この判断だけで十分です。 後のSTEPで、状態管理を整理するときに、この違いが自然と効いてきます。

Column / Row / Expanded / Padding

Flutterのレイアウトは、最初こそ独特に見えますが、実はCSSよりもかなり単純です。 Columnは縦並び、Rowは横並び。これだけ覚えれば、レイアウトの大半は組めます。 Expandedは、「余ったスペースをどう使うか」を制御するためのWidgetです。 Flexboxを使ったことがある人なら、役割としてはかなり近いものがあります。 Paddingは、その名の通り余白を付けるためのWidget。 CSSのmarginやpaddingの指定で悩むことがなく、 「このWidgetに余白を足す」という感覚で書けます。 重要なのは、レイアウトもすべてWidgetであるという点です。 CSSのように、「レイアウトだけ別の言語で考える」必要がないのがシンプルでいいですね。

FlutterのUIはなぜCSSより楽なのか

理由はとてもシンプルです。 Flutterでは、「見た目が壊れる要因が少ない」からです。
・ブラウザ差異がない ・OS差異が少ない ・親要素の影響で突然レイアウトが崩れない
UIがコード通りに描画されるため、「なぜこうなったのか分からない」という瞬間が圧倒的に減ります。 また、UIがツリー構造で表現されるため、画面構造を頭の中で追いやすいのも大きなメリットですね。

成果物:静的な業務画面モック

このSTEPで作る成果物は、動かなくて構いません。 入力フォームや一覧画面など、よくある業務画面を静的に組んでみるだけで十分です。 重要なのは、「このUIはどういう構造のWidgetでできているか」を意識しながら書くことです。 ここでUI構築に慣れておくと、次のSTEP以降でロジックを足すときに、頭が混乱しなくなります。 dart lib/main.dart import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Business Mock', home: const DashboardPage(), debugShowCheckedModeBanner: false, ); } } class DashboardPage extends StatelessWidget { const DashboardPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('顧客管理ダッシュボード'), ), body: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 検索エリア const Text( '検索条件', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 8), Row( children: [ Expanded( child: TextField( decoration: const InputDecoration( labelText: '顧客名', border: OutlineInputBorder(), ), ), ), const SizedBox(width: 12), ElevatedButton( onPressed: null, child: const Text('検索'), ), ], ), const SizedBox(height: 24), // 一覧エリア const Text( '顧客一覧', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 8), Expanded( child: ListView( children: const [ CustomerTile( name: '株式会社サンプル', email: 'sample@example.com', ), CustomerTile( name: 'テスト商事', email: 'test@example.com', ), CustomerTile( name: 'デモ株式会社', email: 'demo@example.com', ), ], ), ), ], ), ), ); } } class CustomerTile extends StatelessWidget { final String name; final String email; const CustomerTile({ super.key, required this.name, required this.email, }); @override Widget build(BuildContext context) { return Card( margin: const EdgeInsets.only(bottom: 8), child: Padding( padding: const EdgeInsets.all(12), child: Row( children: [ const Icon(Icons.business), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( name, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), Text( email, style: const TextStyle(color: Colors.grey), ), ], ), ), ], ), ), ); } }

このモックのポイント

・UIはすべてWidgetの組み合わせ ・レイアウト制御はColumn / Row / Expandedだけ ・CSS的な「崩れ方」を一切考えなくていい ・業務画面の構造がコードからそのまま読める

このステップのあとがき

このSTEPで得られる一番の収穫は、「FlutterでUIを書くのは怖くない」という感覚です。 CSSで悩んできた時間を思い返すと、UIをコードで制御できる安心感は、かなり大きな武器になると思います。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ