Flutterは、ネイティブクロスプラットフォームアプリケーション向けのGoogle製UIフレームワークです。Flutter Docs (2025)によると、FlutterはGoogle Playで50万以上のアプリに使用されています。Widget、StatefulWidget、BuildContext、レンダリングツリーの理解はFlutter開発の基礎です。
重要ポイント
Widget — UIの一部の宣言的な記述。FlutterのすべてはWidgetです:ボタンからアプリ自体まで。Widgetは設定です(UIそのものではありません)。StatelessWidget — 不変のWidget。build()は一度だけ呼び出されます。状態を持ちません。静的コンテンツに使用されます。StatefulWidget — 可変のWidget。変更可能なStateオブジェクトを持ちます。setState() — 再構築をトリガーします。State — StatefulWidgetに紐づく可変オブジェクト。変更可能なデータを含みます。
StatelessWidget — build()は一度だけ呼び出されます。ヘッダー、アイコン、静的テキストに適しています。StatefulWidget — build()はsetState()が呼び出されるたびに実行されます。フォーム、変更のあるリスト、タイマーに適しています。InheritedWidget — コンストラクタを介さずにデータをツリーの下位に渡します。Theme、MediaQuery、Navigator — InheritedWidgetです。BuildContext — ツリー内のWidgetの位置。context.of<T>、context.watch<T>、context.select<T,R> — InheritedWidgetへのアクセス。
// Flutter Widgetの例: setStateを使用するStatefulWidget
class CounterWidget extends StatefulWidget {
const CounterWidget({Key? key}) : super(key: key);
@override
State<CounterWidget> createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _counter = 0;
void _increment() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Flutter Counter')),
body: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('You have pushed the button:'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _increment,
child: const Icon(Icons.add),
),
);
}
}Widget — 設定。StatelessWidget — 不変。StatefulWidget — setState()で可変。IT SectrはStatelessWidgetから始め、状態が必要な場合のみStatefulWidgetに切り替えることを推奨します。
Flutterは効率的なレンダリングのために3つのツリーを使用します。Widget Tree — 設定ツリー。Widgetは頻繁に作成されます(ビルドごと)、軽量です。Element Tree — 要素ツリー。Widgetごとに1つの要素(タイプが変わらない場合)。Element — WidgetとRenderObjectの間のブリッジ。RenderObject Tree — レンダリングツリー。サイズ、位置、描画を処理します。RenderObject — 重く、作成は稀です。FlutterはWidget Treeを比較してElement Treeを更新し、RenderObject Treeの更新をトリガーします。
Key — Element Tree内のWidget識別子。ValueKey、ObjectKey、UniqueKey、PageStorageKey。KeyによりFlutterは再構築時に古いWidgetと新しいWidgetを対応付けられます。Keyがない場合、FlutterはWidgetのタイプと位置で対応付けます。GlobalKey — 別のWidgetからStateにアクセス。使用例:複雑なフォーム、アニメーション、テストでのStateアクセス。IT Sectrはリスト(List.generate)にはKeyを使用し、不要なGlobalKeyは避けることを推奨します。
Expanded — Row/Column/Flexで利用可能なスペースを埋めるWidget。Flexible — 埋めることを強制しません(小さくできます)。MediaQuery — デバイス情報を含むInheritedWidget:画面サイズ、向き、プラットフォーム、テキストスケール係数。Theme/ThemeData — 集中管理されたテーマ。Theme.of(context) — アクセス。MaterialApp — ルーティング、テーマ、ロケール設定のルートWidget。Scaffold — AppBar、Drawer、BottomNavigationBarを含む基本レイアウト。AppBar — 上部パネル。
Navigator — ルートスタック(Routes)。Navigator.push — 画面を開く(Futureを返す)。Navigator.pop — 閉じる(結果付き)。MaterialPageRoute — アニメーション遷移(右からスライド)。Named Routes — 文字列識別子。onGenerateRoute — 集中管理ハンドラー。Navigator 2.0(Router + RouteInformationParser + RouterDelegate) — ウェブ、ディープリンク、複雑なシナリオのための宣言的ナビゲーション。
Navigator 2.0 — 宣言的ナビゲーション。Router — 中央Widget。RouteInformationParser — URL解析。RouterDelegate — スタック管理。GoRouter(パッケージ) — Navigator 2.0の簡略化ラッパー。サポート:名前付きルート、パラメータ、リダイレクト、ディープリンク。IT SectrはほとんどのプロジェクトでGoRouterを、複雑なシナリオ(ウェブ、デスクトップ)でのみNavigator 2.0を推奨します。
FutureBuilder — Futureに基づいてUIを構築するWidget。connectionState:none、waiting、active、done。使用例:HTTPリクエスト、DB読み取り、タイマー。StreamBuilder — Stream用Widget(無限データフロー)。snapshot.data、snapshot.hasError、snapshot.hasData。使用例:WebSocket、Firebase、位置情報更新。両Widgetは新しいデータを受信すると再構築されます。
Provider — シンプルなDI+状態管理。ChangeNotifierProvider、MultiProvider。Riverpod — Providerの現代的代替:コンパイルセーフ、BuildContextに依存しない。Bloc — イベント駆動アーキテクチャ:Cubit(単純イベント)vs Bloc(複雑)。GetX — 軽量な状態管理+DI+ルーティング。setState — 最もシンプル、ローカル状態向け。IT Sectrは新規プロジェクトにRiverpod、既存プロジェクトにProviderを推奨します。
MediaQuery — 画面サイズ、向き、プラットフォーム、textScaleFactor。MediaQuery.of(context).size.width。ThemeData — アプリのテーマ:色、フォント、形状。Theme.of(context).textTheme.bodyLarge。Hot Reload — 実行中のアプリへのコード注入。状態を保持。非サポート:main()の変更、グローバル変数、静的フィールド。Hot Restart — アプリの完全再起動(状態喪失)。Hot Reload — Flutterの開発者にとっての最大の利点。
| Widgetタイプ | 説明 | 例 |
|---|---|---|
| StatelessWidget | 不変、buildは1回 | Text, Icon, Padding, Center |
| StatefulWidget | 可変、setStateで再構築 | TextField, Checkbox, AnimationController |
| InheritedWidget | データを下位に渡す | Theme, MediaQuery, Navigator |
| ProxyWidget | 他のWidgetのラッパー | ParentDataWidget (Positioned, Expanded) |
| RenderObjectWidget | RenderObjectを作成 | Column, Row, Stack(カスタム) |
StatelessWidget — 静的コンテンツに。StatefulWidget — 動的コンテンツに。InheritedWidget — DIに。IT SectrはデフォルトでStatelessWidgetを、必要な場合のみStatefulWidgetを推奨します。
LayoutBuilder — 親の寸法に適応。OrientationBuilder — 向きに適応。Expanded vs Flexible — Row/Column内のスペース配分。MediaQuery — タブレットとデスクトップのブレークポイント。SafeArea — システム要素(ノッチ、ステータスバー)からのマージン。AspectRatio — 比率を維持。IT SectrはアダプティブレイアウトにLayoutBuilder、横向きにOrientationBuilderを推奨します。
単体テスト — ビジネスロジック、リポジトリ、モデルのテスト。dart test — 実行。Widgetテスト — ウィジェットを隔離してテスト。WidgetTester — pumpWidget、tap、enterText。統合テスト — 実機/エミュレータでの完全シナリオ。Mockito — 依存関係のモック。Goldenテスト — スクリーンショット比較(goldenファイル)。IT Sectrは各画面にWidgetテスト、ビジネスロジックに単体テストを推奨します。
void main() {
testWidgets('Counter increments on tap', (tester) async {
await tester.pumpWidget(const MaterialApp(home: CounterWidget()));
expect(find.text('0'), findsOneWidget);
await tester.tap(find.byType(FloatingActionButton));
await tester.pump();
expect(find.text('1'), findsOneWidget);
});
}暗黙的アニメーション — AnimatedContainer、AnimatedOpacity、AnimatedPadding、TweenAnimationBuilder。プロパティ変更が自動的にアニメーション化。明示的アニメーション — Tween付きAnimationController。forward() / reverse()。Heroアニメーション — タグ付きHeroWidget — 画面間の遷移アニメーション。Staggeredアニメーション — Intervalを使ったアニメーションチェーン。Lottie — After Effectsアニメーションの統合。Rive — インタラクティブアニメーション(state machine)。IT Sectrは80%のケースでAnimatedContainer、複雑なシナリオでAnimationControllerを推奨します。
class AnimatedBox extends StatefulWidget {
@override
State<AnimatedBox> createState() => _AnimatedBoxState();
}
class _AnimatedBoxState extends State<AnimatedBox> {
bool _expanded = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => setState(() => _expanded = !_expanded),
child: AnimatedContainer(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
width: _expanded ? 200 : 100,
height: _expanded ? 200 : 100,
color: _expanded ? Colors.blue : Colors.red,
child: const Center(child: Text('Tap me')),
),
);
}
}http — シンプルなHTTPクライアント(get、post、put、delete)。dio — インターセプター、タイムアウト、リトライ、ロギング付きの高度なクライアント。graphql_flutter — Flutter用GraphQLクライアント。json_serializable — アノテーションによるfromJson/toJson生成。Retrofit Dart — Retrofitのようなtype-safe HTTPクライアント。WebSocket — web_socket_channel経由。Firebase — Cloud Firestore、Realtime Database、Cloud Functions。IT SectrはREST APIにdio、GraphQLにgraphql_flutterを推奨します。
Flutter DevTools — ツールセット:Inspector(ウィジェットツリー)、Timeline(パフォーマンス)、Memory、Network、Logging。Profile mode — デバッグなしのプロファイリング。Performance overlay — FPS、ビルド時間。Flame chart — フレームチャートトレーシング。DevTools — 本番環境でのFlutterアプリケーション最適化に不可欠なツール。
Flutter Web — FlutterをWASM(WebAssembly)にコンパイル。CanvasKit(Skia)vs HTML renderer。CanvasKit — ピクセルパーフェクトだが重い。HTML renderer — 軽量だが制限あり。WASM(Flutter 3.22+) — ネイティブパフォーマンス。LayoutBuilderとMediaQueryによるレスポンシブ適応。IT SectrはデスクトップウェブアプリケーションにCanvasKit、コンテンツサイトにHTML rendererを推奨します。
よくある質問
StatelessWidget — 不変、buildは1回。StatefulWidget — 可変なStateとsetState()を持つ。
Widget Tree — 設定。Element Tree — ブリッジ。RenderObject Tree — レンダリング(サイズ、描画)。
BuildContext — ツリー内のWidget位置。InheritedWidget — データを下位に渡す(Theme、MediaQuery)。
Navigator — 画面スタック。push() → pop()。Named Routes — 文字列名。Navigator 2.0 — 宣言的。
Hot Reload — 1〜2秒でコード注入、状態保持。Hot Restart — 完全再起動。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。