【Flutter】StatefulWidgetの作り方

2021/12/22に公開

はじめに

はじめまして。フルゲンと申します。
StatefulWidgetの作り方について調べたので、
内容をFlutterのサンプルのカウンターアプリを例にまとめてみました。
Flutter学習のお役に立てれば幸いです。

StatefulWidgetの作り方

※Android Studioでは"stful"入力でStatefulWidgetのテンプレが作成できる。

1. StatefulWidgetをExtendsしたクラスを作る。

  • 変数をもたすことも可能。
  • createState()でState(StateをExtendsしたクラス)を返す。
// 1. StatefulWidgetを継承したクラスを作る。
class MyHomePage extends StatefulWidget {  

  // 変数定義すると、UIのところから"widget.変数名" で呼ぶことができる。
  final String title;

  const MyHomePage({
    Key? key,
    required this.title,
  }) : super(key: key);
  
   // createState() で"State"(Stateを継承したクラス)を返す
  
  _MyHomePageState createState() => _MyHomePageState();
}

2. StateをExtendsしたクラスを作る(上記のcreateState()で返されるクラス)

  • Stateのクラス名は上で作った、StatefulWidgetのクラス名 + "State" (例: MyHomePageState )とする。
  • 変更するフィールドを定義
  • 変更するメソッドを定義し、変更する部分をsetState()で包む。
// 2. StateをExtendsしたクラスを作る(上記のcreateState()で返されるクラス)
class _MyHomePageState extends State<MyHomePage> {
  
  // クラスのフィールドとしての状態保持
  // providerのmodelで定義しているfieldにあたる 
  int _counter = 0;
  
  // providerのモデルで定義していたmethodをここかく。
  void _incrementCounter() {
    // 変更したらUIも変わる操作をsetStateで包む。
    //(providerのchangeNotifier()みたいな役割) 
    setState(() {
      _counter++;
    });
}
  • build関数をオーバーライドしてWidgetを作ることで、UIを作る
// _MyHomePageStateのbuildメソッド
// 状態を使いつつ組んだWidgetを返す(build関数)    

Widget build(BuildContext context) {
    // UIの部分はここに書く。 
    return Scaffold();
} 

以下サンプルコード

(Flutterのサンプル カウンターアプリ)

import 'package:flutter/material.dart';

Future<void> main() async => runApp(MyApp());

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

// 1. StatefulWidgetを継承したクラスを作る。
class MyHomePage extends StatefulWidget {  
  final String title;

  const MyHomePage({
    Key? key,
    required this.title,
  }) : super(key: key);
  // createState() で"State"(Stateを継承したクラス)を返す
  
  _MyHomePageState createState() => _MyHomePageState();
}

//  2.Stateを継承したクラスを作る。
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  
  // providerのモデルで定義していたmethodをここかく。
  void _incrementCounter() {
    // 変更したらUIも変わる操作をsetStateで包む。
    //(providerのchangeNotifier()みたいな役割) 
    setState(() {
      _counter++;
    });
  }

  // 状態を使いつつ組んだWidgetを返す(build関数)    
  
  Widget build(BuildContext context) {
    //  UIの部分はここに書く。 
    return Scaffold(
      appBar: AppBar(
        // このように自分(State)をcreateStateしたWidget(StatefulWidget)
        // のフィールドにアクセスできる。
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),

      // ボタン操作に応じて_counterを増やす
      floatingActionButton: FloatingActionButton(
        // onPressedされると、_counter++され、setState()によってUIが再描画される。
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

さいごに

ここまで読んでいただき、ありがとうございました!
間違いなどございましたら、ご指摘いただけると幸いです。

参考サイト

以下参考にさせて頂きました。ありがとうございました!
https://medium.com/flutter-jp/first-step-9b7f2c74fb08

https://tech-rise.net/difference-between-stateless-widget-and-stateful-widget

Discussion