[Flutter]StatelessWidgetとStatefulWidget

2 min read読了の目安(約2000字
  • WidgetはStatelessWidgetかStatefulWidgetかのどちらかに属するよ
  • Statelessは変化しないWidgetだよ
  • Statefulは変化するWidgetだよ。ユーザーのインタラクションに応じて変化するよ。例えばRadio、Checkboxとかがそれにあたるよ
  • Widgetの状態はStateというオブジェクトに格納されて、外観とは分離して管理されるよ
  • Stateでは変化対象の値を持ち、変化を通知するsetStateメソッドを持つよ
  • setStateが呼び出されると、フレームワークが対象のStatefulWidgetを再描画するよ

StatefulWidgetをつくる

  • 自分で独自のStatefulWidgetをつくることができるよ
  • このとき、作るものが2つあるよ
  1. StatefulWidgetを継承したクラス
  2. Stateを継承したクラス

StatefulWidgetクラス

  • StatefulWidgetを継承したクラスを定義するよ
  • StatefulWidgetにはcreateStateというメソッドがあり、overrideするよ
  • createState()はStateオブジェクトを返すよ
  • nextでいう、useStateにあたる気がするよ
class FavoriteWidget extends StatefulWidget {
  
  _FavoriteWidgetState createState() => _FavoriteWidgetState();
}

Stateクラス

  • Stateを継承したクラスを定義するよ
  • 継承するとき、StateクラスにGenericで自分で作成したStatefulWidgetを指定するよ
  • Stateで管理したい値をインスタンス変数で持つよ
  • Stateはbuildメソッドを持つのでoverrideしてUIを定義するよ
  • この中ではStateの値にアクセスできるよ
class _FavoriteWidgetState extends State<FavoriteWidget> {
  bool _isFavorited = true;
  int _favoriteCount = 41;

  
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        Container(
          padding: EdgeInsets.all(0),
          child: IconButton(
            padding: EdgeInsets.all(0),
            alignment: Alignment.centerRight,
            icon: (_isFavorited ? Icon(Icons.star) : Icon(Icons.star_border)),
            color: Colors.red[500],
            onPressed: _toggleFavorite,
          ),
        ),
        SizedBox(
          width: 18,
          child: Container(
            child: Text('$_favoriteCount'),
          ),
        ),
      ],
    );
  }
}
  • さらにStateの値を変更するメソッドを追加してみるよ
void _toggleFavorite() {
  setState(() {
    if (_isFavorited) {
      _favoriteCount -= 1;
      _isFavorited = false;
    } else {
      _favoriteCount += 1;
      _isFavorited = true;
    }
  });
}
  • setStateメソッドを呼び出して、そのなかでStateの値を変更するよ
  • そうすると変更された値でStatefulWidgetが再描画されるよ
  • このように状態を持つWidgetを独自に定義して、ユーザーの操作に応じて状態を変更していくことで、インタラクティブなアプリを作っていくことができるよ