flutter初学者のためのコードの追い方
2025 年 3 月 1 日 by marukorはじめに
最近flutterの学習を始めました。web系の開発しかやってこなかったのでファイルの構成やコードの見方に苦戦しました。ここではフォルダの構成からコードの追い方について説明していきます。
環境
os mac
flutter-version 3.27.1
まずはプロジェクトを作成する
何でもいいので以下のコマンドでプロジェクトを作成してください。
flutter create [プロジェクト名]
フォルダの中身
プロジェクトを作成すると以下のようなディレクトリが作成されたと思います。

この中でプログラムを書いていくのはlibの中になります。
ここがディレクトリを作成したり、ファイルを追加したりしてプログラムを構築していく場所になります。
libの中にはプロジェクトを作った際に作られるmain.dartがあります。
main.dartというファイルが Flutter アプリのエントリーポイントとなるファイルになります。
その他の開発の際に触る主なファイルの説明は以下です。
パッケージ管理ファイル
Flutter のパッケージ管理に関するファイルです。pubspec.yamlはflutterの依存関係を記述するファイルになります。
Platform ごとのディレクトリ
iOS、Android、Web、macOS、Linux、Windows それぞれのプラットフォーム向けにネイティブコードをカスタマイズしたり、プラットフォーム特有の機能を追加したりする場合に使用します。
コード構成
flutterで実際の UI を作っていく上で、最も重要なのが Widget です。Flutter では、UI を構成する各要素を Widget と呼びます。親widgetが子widget を持ちその子widgetが、また子widget を持つようにしてツリー構造のようにしてUIが構築されていきます。
つまりflutterではこのwidgetを見てコードを追っていくようになります。
実際のコードではwidgetはどこのことなのか
こちらのプロジェクトを作成した際にデフォルトで作成されるカウンターアプリを見ながらコードの構成を追っていきます。

main.dart
class MyApp extends StatelessWidget { const MyApp({super.key}); // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } }
ここが一番初めに実行されているツリー構造の一番上に当たるwidgetです。
StatelessWidget を使用していますが、それについては後ほど説明します。
ここではテーマカラーの設定やデフォルトフォントなどの、プロジェクト全体の設定を行なっています。
画面を作っているwidget
MyHomePage(title: 'Flutter Demo Home Page')
このwidgetで画面のボタンやカウンターの部分などを作成しています。
定義されている部分はここです。
class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ const Text( 'You have pushed the button this many times:', ), Text( '$_counter', style: Theme.of(context).textTheme.headlineMedium, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), ), // This trailing comma makes auto-formatting nicer for build methods. ); } }
ここではStatefulWidgetを使用していますね。
ではこのStatefulWidgetとStatelessWidget とはいったい何なのか、簡単に説明します。
StatelessWidget
StatelessWidget は、一度作成されると状態を持たず、不変なウィジェットです。
画面に表示される内容が変わらない場合に使用されます。
例えば、次のような StatelessWidget は単純なテキストを表示するだけで、内部の状態は変更されません。
class MyStatelessWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Text('私はStatelessWidgetです'); } }
この MyStatelessWidget は、初期化された後に setState() で更新することはできません。
StatefulWidget
一方、StatefulWidget は内部に状態(State)を持ち、変更があるたびに再描画されるウィジェットです。
ユーザーの操作や時間経過によって画面の表示が変わるような場合に適しています。
例えば、今回のカウンターアプリのようにボタンを押すたびにカウントが増えるので StatefulWidget を使用しています。
カウンターのアプリの処理を見ていく
StatefulWidgetとStatelessWidget について理解できたところで、実際のコードの中身を見ていきます。
class _MyHomePageState extends State<MyHomePage> { int _counter = 0; // カウンターの状態 void _incrementCounter() { setState(() { _counter++; // ボタンが押されるたびにカウンターを増やす }); } }
この部分でボタンが押された回数をカウントする状態を管理しています。
floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), ), // This trailing comma makes auto-formatting nicer for build methods.
この部分でボタンが押された時にカウントするメソッドを呼び出しています。
状態変化の流れ
1. 状態が変化する流れ 初期値 _counter = 0 で画面に表示。
2. FloatingActionButton(+ ボタン)を押すと _incrementCounter() が呼ばれる。
3. setState() により _counter が増え、画面が再描画される。
まとめ
今回はほんとに初歩の部分を見ていきました。
意外に初歩の部分って記事などが少なく困ることが多いので、誰かの役に立てると嬉しいです。