Flutterのフレームワークとして、StatelessWidget と StatefullWidgetの理解することが大切で
その意味と使い方を考えてみます
StatelessWidget と StatefullWidget
StatelessWidget と StatefullWidget は Flutter の基本的な要素です
この2つを理解するまえに、Widget と State の概念も理解しておく必要があります
Widget と State
Widget:
UI、ユーザーインターフェースの構成要素のことです
テキストやボタンのほかレイアウト構造などすべてのUI要素が
Widgetとして構築されています
State:
これは状態を意味するもので
FlutterではStateクラスとしてWidgetの状態を管理するのに使われます
StatelessWidget と StatefullWidget
ざっくり2つの違いは、
StatelessWidget:
- 状態を持たない静的なWidget(静的ではない使い方もあります)
- build メソッドを持ち、Wdgetを返す
StatefullWidget:
- State(状態)を持っている動的なWdget
- 状態を変化させるときは setState の引数コールバックで行う
- stateの変化に応じて再描画
これ以外にもあげればたくさんありますがとりあえずここまで
StatelessWidget
例えば、プロジェクトの作成で「Empty Application」を選択してできるコードは
Hello World! が表示される StatelessWidget だけでできています
main.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import 'package:flutter/material.dart'; void main() { runApp(const MainApp()); } class MainApp extends StatelessWidget { const MainApp({super.key}); // build関数をoverride(上書き)してWidget(ここではMaterialApp)を返す @override Widget build(BuildContext context) { return const MaterialApp( home: Scaffold( body: Center( child: Text('Hello World!'), ), ), ); } } |
MaterialApp Widget:
ルートWidgetで、アプリ全体を管理
Googleの提唱するデザインシステムである、Material Designでの
開発が容易にできる
Scaffold Widget:
アプリ画面の土台(足場)を形成して、その上にAoobarやbodyなど
様々なWidgetを載せて表示させる
Center Widget:
Scaffold の引数のbodyに設定されていてText Widgetのレイアウトを
画面中央に配置している
Text Widget:
言うまでもなくテキストを表示させるWidgetです
StatefullWidget
プロジェクトの作成で「Application」を選択してできるコードは
ボタンをタップするとカウンターが0から増加する、つまり状態が変わるアプリです
main.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } 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'), ); } } //------------------------------------ // StatefullWidget を継承したクラス HomePage の作成 //------------------------------------ class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; // createState()を使ってStateを継承したクラスを返す @override State<MyHomePage> createState() => _MyHomePageState(); } // (前の createState()で返されるクラス) Stateを継承したクラスを作る class _MyHomePageState extends State<MyHomePage> { int _counter = 0; void _incrementCounter() { // 変更するとUIも変わる操作を setState で囲む // これが呼ばれると歳buildされる setState(() { _counter++; }); } // build関数をoverride(上書き)してWidgetをつくり、UIを作成 @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. ); } } |
References:
StatelessWidget class – Dart API
StatefulWidget class – Dart API