【Flutter入門】StatelessWidgetとStatefulWidgetの違い

StatelessWidgetとStatefulWidgetの違いとは

本記事は、マルチプラットフォーム開発のSDK【Flutter】を用いたモバイルアプリ開発入門の為の記事です。

ダーフク

Flutterを用いたアプリを開発する際、まず始めに目にするのがこのStatelessWidgetStatefulWidgetです。本記事では、これら2つの違いに付いて、サンプルを交えながら解説していきます。

StatelessWidget

StatelessWidgetとは、State(状態)を持たないWidgetのことです。

なので変数を定義しても、その変数は親Widgetより渡されるのみで、自分でその値を更新することはできません。

また、このような特性ゆえ、静的なWidgetであると言えます。

 

以下にサンプルのソースコードを挙げます。

class SampleStatelessClass extends StatelessWidget {
  final String text;

  SampleStatelessClass({@required this.text});

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: Text(text),
      ),
    );
  }
}

StatelessWidgetは、build関数をoverride(上書き)し、build関数内で描画するWidgetを返すことで描画を行なっています。

 

もし子WidgetであるStatelessWidgetで使用した変数を親Widgetにて変更した場合、子であるStatelessWidgetは全て再描画(build)されます。

StatefulWidget

StatefulWidgetとは、State(状態)を持つWidgetのことです。

状態を持つため、自分の変数を更新することで自分自身を再ビルドすることができます。

ゆえに、StatefulWidgetは動的なWidgetです。

 

以下にサンプルのソースコードを挙げます。

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
  // setStateで変数を上書きし、再ビルドする
    setState(() => _counter++);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
    // 親Widgetから渡された変数にアクセスする
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            SampleStatelessClass(
              text: 'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

StatefulWidgetを実装するためには、2種類のclassを作成する必要があります。

  1. StatefulWidgetをextendsしたclass
  2. State<1.で作成したクラス>をextendsしたclass

➀StatefulWidgetについて

➀は大元のStatefulWidgetで、createState()をoverrideし、➁のStateを呼び出す必要があります。

@override
_MyHomePageState createState() => _MyHomePageState();

➁Stateについて

➁は状態を管理するStateクラスです。

ここでStatelessWidgetと同じく、build関数をoverrideし描画するWidgetを返します

@override
Widget build(BuildContext context) {
  return Scaffold();

 

また、setStateを呼ぶことで変数が更新され、再buildされます。

void _incrementCounter() {
  setState(() => _counter++);
}

 

StatefulWidgetで定義した変数にアクセスしたい場合は、widget.変数名とすることで可能です。

appBar: AppBar(
  title: Text(widget.title),
),

ライブテンプレート機能を用いた実装の簡略化

Intellij IDEAとAndroid Studioを使っている方は、ライブテンプレート機能を用いることで、数文字入れるだけで雛形を作成することができます。

上記のエディターを使っている方は、この機能を利用することをお薦めします。

StatefulWidgetの場合【stful】、StatelessWidgetの場合【stless】、と入力すると雛形が表示されます。

この他にも開発に使えるTIPSを別記事にまとめています。

Flutter開発の爆速効率化【Flutter】IDEでモバイルアプリ開発を激効率化にする方法

まとめ

Flutterでのアプリ開発を始めると、最初に目にするのがこのStatelessWidgetとStatefulWidgetです。

本記事では、その主な違いについて、説明しました。

まずはここから理解を進めていくと良いかなと思います。

 

StatelessWidget

  • 状態を持たない静的なWidget
  • 不変なWidgetを描画する場合はこれを用いる
StatefulWidget

  • 状態を保持する動的なWidget
  • 値が変わる可能性があるWidgetを描画する場合はこれを用いる

 

その他にも、Flutterに関する記事を以下にまとめています。

Flutter アイキャッチ