Flutter: Flutter入門と環境構築

Flutterを使えば、1つのDartコードベースでiOS、Android、Web、Desktopのアプリを構築できます — まるで1つのマスターキーで4つのドアを開けるように。

📋 前提条件: 事前の経験は不要です

1. このレッスンで学ぶこと


2. 起業家のリアルなストーリー

(1) 悩み:4つのプラットフォーム、4つのコードベース

Bobは起業家で、ShopAppというECプロジェクトをiOS、Android、Web、Desktopで同時に展開する必要があります。各プラットフォームに独自のネイティブコードベースが必要だと、4つの開発チームと4つのコードベースが必要になり、人件費は年間50万ドルを超えます。さらに、キャンペーンの立ち上げには要件定義から6週間かかります — 各チームが個別に実装しなければならないからです。

(2) Flutterのソリューション

Flutterは「一度書けば、どこでも動く」戦略を採用し、DartでUI層を記述し、独自の描画エンジンで直接ピクセルをレンダリングします。ネイティブUIコンポーネントには依存しません。

DART
import 'package:flutter/material.dart';

// One codebase, four platforms
void main() => runApp(const ShopApp());

class ShopApp extends StatelessWidget {
  const ShopApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ShopApp',
      home: Scaffold(
        appBar: AppBar(title: const Text('ShopApp')),
        body: const Center(child: Text('Hello, Bob!')),
      ),
    );
  }
}
TEXT 📖 参照専用
> **出力:** Flutter SDK(Flutter 3.x / Dart 3.x)でローカルに実行してください。PistonサーバーにはFlutterがインストールされていません。ローカルマシンで`flutter run`を使用して比較してください。実際のUI/状態はプラットフォームにより多少異なる場合があります。

(3) 結果:1つのチームが4つを代替

Flutterを採用後、Bobの1つのチームが1つのコードベースを保守し、4つのプラットフォームで同時にリリースできるようになりました。キャンペーンの期間は6週間から1週間に短縮され、年間開発コストは50万ドルから15万ドルに削減されました。


3. Flutterの技術アーキテクチャ

Flutterはレイヤー化されたアーキテクチャを採用しており、上位のFrameworkから下位のEngineまで、それぞれが独自の責務を持ちます。

100%
graph TD
    A[Flutter SDK] --> B[Dart SDK]
    A --> C[Framework Layer]
    A --> D[Engine Layer]
    C --> E[Material Library]
    C --> F[Cupertino Library]
    D --> G[Skia / Impeller]
    D --> H[Platform Embedder]
    H --> I[Android]
    H --> J[iOS]
    H --> K[Web]
    H --> L[Windows/macOS/Linux]
TEXT 📖 参照専用
> **出力:** Flutter SDK(Flutter 3.x / Dart 3.x)でローカルに実行してください。PistonサーバーにはFlutterがインストールされていません。ローカルマシンで`flutter run`を使用して比較してください。実際のUI/状態はプラットフォームにより多少異なる場合があります。

(1) Frameworkレイヤー

Frameworkレイヤーは開発者が直接操作する部分で、すべてDartで書かれています:

レイヤー 責務 言語
Widget UI設定の宣言 Dart
Element Widgetツリーの差分管理 Dart
RenderObject レイアウトと描画 Dart
Engine レンダリングとI/O C++

(2) Engineレイヤー

EngineレイヤーはC++で書かれており、主要コンポーネントは以下の通りです:

💡 ヒント: Flutter 3.xではImpellerレンダリングエンジンがデフォルトで有効になり、Skiaに代わって初回フレームのカクつきとシェーダーコンパイルの遅延を解決します。

(3) Platform Embedder

各プラットフォームには異なるEmbedderの実装があり、以下を担当します:

プラットフォーム Embedder レンダリング方式
Android flutter_shell (Java/Kotlin) GPU (Vulkan/OpenGL)
iOS FlutterViewController (Swift/ObjC) GPU (Metal)
Web HTML Canvas / WebGL CanvasKit / HTML renderer
Desktop GLFW / Win32 / Cocoa GPU

4. Everything is a Widget

Flutterの中核哲学:すべてはWidgetです。ボタン、フォント、スペーシング、さらにはレイアウトの制約もすべてWidgetです。

(1) Widgetの分類

種類 説明
StatelessWidget 不変、一度だけビルド Text, Icon, Image
StatefulWidget 可変状態、再ビルド可能 TextField, Checkbox
RenderObjectWidget レイアウトと描画を制御 Flex, Stack, Positioned
ProxyWidget サブツリーにデータを渡す InheritedWidget, Provider

▶ サンプル

TEXT 📖 参照専用
> **出力:** Flutter SDK(Flutter 3.x / Dart 3.x)でローカルに実行してください。PistonサーバーにはFlutterがインストールされていません。ローカルマシンで`flutter run`を使用して比較してください。実際のUI/状態はプラットフォームにより多少異なる場合があります。

: StatelessWidgetの商品カード

DART
import 'package:flutter/material.dart';

class ProductCard extends StatelessWidget {
  final String name;
  final double price;

  const ProductCard({
    super.key,
    required this.name,
    required this.price,
  });

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(name, style: const TextStyle(fontSize: 18)),
            Text('\$${price.toStringAsFixed(2)}',
                style: const TextStyle(color: Colors.green, fontSize: 16)),
          ],
        ),
      ),
    );
  }
}
TEXT 📖 参照専用
> **出力:** Flutter SDK(Flutter 3.x / Dart 3.x)でローカルに実行してください。PistonサーバーにはFlutterがインストールされていません。ローカルマシンで`flutter run`を使用して比較してください。実際のUI/状態はプラットフォームにより多少異なる場合があります。

▶ サンプル

TEXT 📖 参照専用
> **出力:** Flutter SDK(Flutter 3.x / Dart 3.x)でローカルに実行してください。PistonサーバーにはFlutterがインストールされていません。ローカルマシンで`flutter run`を使用して比較してください。実際のUI/状態はプラットフォームにより多少異なる場合があります。

: StatefulWidgetのカウンター

DART
import 'package:flutter/material.dart';

class QuantitySelector extends StatefulWidget {
  const QuantitySelector({super.key});

  @override
  State<QuantitySelector> createState() => _QuantitySelectorState();
}

class _QuantitySelectorState extends State<QuantitySelector> {
  int _count = 1;

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        IconButton(
          icon: const Icon(Icons.remove),
          onPressed: () => setState(() => _count = (_count - 1).clamp(1, 99)),
        ),
        Text('$_count', style: const TextStyle(fontSize: 20)),
        IconButton(
          icon: const Icon(Icons.add),
          onPressed: () => setState(() => _count++),
        ),
      ],
    );
  }
}
TEXT 📖 参照専用
> **出力:** Flutter SDK(Flutter 3.x / Dart 3.x)でローカルに実行してください。PistonサーバーにはFlutterがインストールされていません。ローカルマシンで`flutter run`を使用して比較してください。実際のUI/状態はプラットフォームにより多少異なる場合があります。

5. 環境構築

(1) Flutter SDKのインストール

手順 Windows macOS Linux
SDKのダウンロード flutter.dev/docs/get-started/install/windows flutter.dev/docs/get-started/install/macos flutter.dev/docs/get-started/install/linux
展開パス C:\flutter ~/development/flutter ~/development/flutter
PATH設定 システム環境変数に追加 ~/.zshrcに追加 ~/.bashrcに追加

▶ サンプル

TEXT 📖 参照専用
> **出力:** Flutter SDK(Flutter 3.x / Dart 3.x)でローカルに実行してください。PistonサーバーにはFlutterがインストールされていません。ローカルマシンで`flutter run`を使用して比較してください。実際のUI/状態はプラットフォームにより多少異なる場合があります。

: PATH設定(macOS/Linux)

BASH
# Add Flutter to PATH in ~/.zshrc or ~/.bashrc
export PATH="$HOME/development/flutter/bin:$PATH"

# Verify installation
flutter --version
# Output: Flutter 3.x.x • channel stable
TEXT 📖 参照専用
> **出力:** Flutter SDK(Flutter 3.x / Dart 3.x)でローカルに実行してください。PistonサーバーにはFlutterがインストールされていません。ローカルマシンで`flutter run`を使用して比較してください。実際のUI/状態はプラットフォームにより多少異なる場合があります。

▶ サンプル

TEXT 📖 参照専用
> **出力:** Flutter SDK(Flutter 3.x / Dart 3.x)でローカルに実行してください。PistonサーバーにはFlutterがインストールされていません。ローカルマシンで`flutter run`を使用して比較してください。実際のUI/状態はプラットフォームにより多少異なる場合があります。

: flutter doctorによる確認

BASH
# Run doctor to check all dependencies
flutter doctor

# Expected output:
# [✓] Flutter (Channel stable, 3.x.x)
# [✓] Android toolchain
# [✓] Chrome - develop for the web
# [✓] Android Studio
# [!] VS Code (install Flutter extension)
TEXT 📖 参照専用
> **出力:** Flutter SDK(Flutter 3.x / Dart 3.x)でローカルに実行してください。PistonサーバーにはFlutterがインストールされていません。ローカルマシンで`flutter run`を使用して比較してください。実際のUI/状態はプラットフォームにより多少異なる場合があります。

(2) IDEの設定

IDE 必須プラグイン 推奨プラグイン
VS Code Flutter, Dart Flutter Widget Snippets, Error Lens
Android Studio Flutter, Dart Flutter Intl, Riverpod Snippet

▶ サンプル

TEXT 📖 参照専用
> **出力:** Flutter SDK(Flutter 3.x / Dart 3.x)でローカルに実行してください。PistonサーバーにはFlutterがインストールされていません。ローカルマシンで`flutter run`を使用して比較してください。実際のUI/状態はプラットフォームにより多少異なる場合があります。

: 最初のプロジェクトを作成

BASH
# Create a new Flutter project
flutter create shop_app

# Navigate to project directory
cd shop_app

# Run on connected device or emulator
flutter run
TEXT 📖 参照専用
> **出力:** Flutter SDK(Flutter 3.x / Dart 3.x)でローカルに実行してください。PistonサーバーにはFlutterがインストールされていません。ローカルマシンで`flutter run`を使用して比較してください。実際のUI/状態はプラットフォームにより多少異なる場合があります。

6. 最初のHello World

▶ サンプル

TEXT 📖 参照専用
> **出力:** Flutter SDK(Flutter 3.x / Dart 3.x)でローカルに実行してください。PistonサーバーにはFlutterがインストールされていません。ローカルマシンで`flutter run`を使用して比較してください。実際のUI/状態はプラットフォームにより多少異なる場合があります。

: ShopApp Hello World

DART
import 'package:flutter/material.dart';

void main() {
  runApp(const ShopApp());
}

class ShopApp extends StatelessWidget {
  const ShopApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'ShopApp',
      theme: ThemeData(
        colorSchemeSeed: Colors.blue,
        useMaterial3: true,
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('ShopApp')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Icon(Icons.shopping_bag, size: 80, color: Colors.blue),
            const SizedBox(height: 16),
            const Text('Welcome to ShopApp!',
                style: TextStyle(fontSize: 24)),
            const SizedBox(height: 8),
            Text('Million-level products, USD settlement',
                style: TextStyle(fontSize: 14, color: Colors.grey[600])),
            const SizedBox(height: 24),
            ElevatedButton(
              onPressed: () {},
              child: const Text('Start Shopping'),
            ),
          ],
        ),
      ),
    );
  }
}
TEXT 📖 参照専用
> **出力:** Flutter SDK(Flutter 3.x / Dart 3.x)でローカルに実行してください。PistonサーバーにはFlutterがインストールされていません。ローカルマシンで`flutter run`を使用して比較してください。実際のUI/状態はプラットフォームにより多少異なる場合があります。

▶ サンプル

TEXT 📖 参照専用
> **出力:** Flutter SDK(Flutter 3.x / Dart 3.x)でローカルに実行してください。PistonサーバーにはFlutterがインストールされていません。ローカルマシンで`flutter run`を使用して比較してください。実際のUI/状態はプラットフォームにより多少異なる場合があります。

: ホットリロードの体験

BASH
# Start app with hot reload support
flutter run

# After modifying code, press:
# r - Hot reload (keep state, update UI)
# R - Hot restart (reset state, rebuild)
# q - Quit

# Hot reload updates UI in <1 second
# Try: change 'Welcome to ShopApp!' to 'Hello Bob!'
# Press r → UI updates instantly
TEXT 📖 参照専用
> **出力:** Flutter SDK(Flutter 3.x / Dart 3.x)でローカルに実行してください。PistonサーバーにはFlutterがインストールされていません。ローカルマシンで`flutter run`を使用して比較してください。実際のUI/状態はプラットフォームにより多少異なる場合があります。

7. Flutter 3.xの新機能

機能 説明 影響
Impellerエンジン プリコンパイル済みシェーダー、初回フレームのカクつきを解消 レンダリング性能30%以上向上
折りたたみ端末対応 折りたたみ画面向けのアダプティブレイアウト 対応デバイスの拡大
Material 3 新しいデザイン仕様、ダイナミックカラー よりモダンなUI
macOS / Linux安定版 公式Desktopプラットフォームサポート 4プラットフォーム完全対応
レンダリングエンジン 初回フレーム時間 シェーダーコンパイル 対象バージョン
Skia 200-500ms 実行時JITコンパイル Flutter 2.x
Impeller <50ms ビルド時AOTコンパイル Flutter 3.x

❓ よくある質問

Q FlutterとReact Nativeの違いは?
A Flutterの独自描画エンジンはネイティブコンポーネントに依存しないため、UIの整合性に優れています。React NativeはJS Bridgeを通じてネイティブコンポーネントを呼び出すため、パフォーマンスのボトルネックになります。
Q Dartは難しいですか?
A Dartの構文はJavaやJavaScriptに似ています。どちらかの経験があれば、1〜2日で始められます。
Q flutter doctorが「Android licenses not accepted」と表示される場合?
A flutter doctor --android-licensesを実行し、各ライセンスを順に承認してください。
Q Flutter Webは本番環境で使えますか?
A Flutter 3.xのWebは安定していますが、SEO対応には限界があります。管理ダッシュボードやツールアプリには適していますが、SEO重視のコンテンツサイトには不向きです。
Q Impellerエンジンは手動で有効にする必要がありますか?
A Flutter 3.16+ではAndroid/iOSでImpellerがデフォルトで有効になります。手動設定は不要です。
Q 開発ではJITとAOTのどちらを使うべきですか?
A 開発中はJIT(ホットリロード対応)、リリースではAOT(最適なパフォーマンス)を使用してください。Flutterが自動的に処理します。

📖 まとめ


📝 練習問題

  1. 基本(難易度 ⭐): コンピュータにFlutter SDKをインストールし、flutter doctorを実行して、少なくとも4項目が合格することを確認してください。
  2. 中級(難易度 ⭐⭐): Hello Worldの例を修正し、現在の日付を表示するTextウィジェットを追加してください。
  3. チャレンジ(難易度 ⭐⭐⭐): 3つの商品カードを持つColumnを作成し、各カードに商品名とドル価格を表示してください。カードをクリックするとSnackBarで商品情報を表示するようにしてください。

← 前へ | 次へ →

Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%