Flutter入門 | Stateクラスの利用、StatefulWidgetについて!! - mohumohu studio

mohumohu studio

           

みずきの技術&読書ブログ&無料ゲーム

プロフィール画像

Flutter入門 | Stateクラスの利用、StatefulWidgetについて!!

今回の記事ではStatefulWidgetについて解説していきながら、ボタンを押したら動的に表示が変わるアプリを作っていきたいと思います!!


目次

  1. StatefulWidgetについて
  2. ステートを操作する
  3. FlotingActionButtonをタップする
  4. 複雑な値の利用
  5. まとめ

StatefulWidgetについて

前回の記事で利用したStatelessWidgetはステートを持たないウィジェットです。

ステートとはアプリの状態を保持するための仕組みです。

つまり、ステートがないということは最初に表示された状態のまま何も変化しないということです。

ですが、実際のアプリでは動的に表示が変わるのが当たり前です。

こうした動的に表示が変わるアプリはStatelessWidgetでは作れなません。

なので今回解説していくStatefulWidgetを使います。

StatefulWidgetとState

StatefulWidgetというクラスは状態を扱う機能を持っています。

これはStateというクラスで用意されています。

整理すると以下の形で定義されます。

StatefulWidgetクラスの基本型

Stateクラスの基本型

StatefulWidgetクラスはウィジェット部分(StatefulWidgetクラス)、ステート部分(Stateクラス)の二つの部分で構成されています。

ウィジェットクラス

ウィジェットクラスはStatefulWidgetクラスを継承して定義します。

このクラスにはcreateStateというメソッドを実装する必要があります。

これはステートを作成するためのもので、一般にはステートクラスのインスタンスを作成して返すだけのシンプルな処理を用意します。

ステートクラス

ステートクラスはStateクラスを継承して作成します。

このとき、ウィジェットクラスを<>で囲って指定しておきます。

これで指定したウィジェットクラスで使われるステートクラスが定義できます。

ステートクラスにはbuildというメソッドが用意されています。

これはステートを生成する際に呼び出され、ここでステートとして表示されるウィジェットを返します。

ウィジェットクラスのcreateStateでステートクラスのインスタンスが使われ、これによってステートクラスのbuildで生成されたウィジェットが、ウィジェットクラスの表示として画面に表示されるようになります。

buildは常に呼び出される

buildはインスタンス生成時に呼び出されるというように理解するのではなく、ステートを生成するためのStateクラスのメソッドで、ステートの値を変更したりするときにも呼び出され、新たな表示を作成しているものと理解しましょう。

つまり、StatefulWidgetというのはステートが更新されるたびに、buildで新たな表示内容を生成して画面に表示するクラスです。


ステートを操作する

では、実際にステートを操作するサンプルを実装していきましょう。

main.dartを以下のように書き換えてください。

実行すると簡単なメッセージが表示されました。

これはステートを使って画面を表示させていますが、まだステートを操作する処理は何も用意していません。ただ、StatefulWidgetを使ったウィジェットがどういったものか、サンプルとして表示してみただけのものです。

ステートクラスとの連携

ここではMyHomePageというウィジェットクラスをStatefulWidgetクラスとして作成しています。

そして、_MyHomePageStateというステートクラスを用意し、ステートとして設定しています。

ステートの設定を行なっているcreateStateメソッドを見ると以下のようになっているのがわかります。

_MyHomePageStateインスタンスを作成し、返しています。

これで_MyHomePageStateクラスがステートとして扱われるようになります。

この_MyHomePageStateクラスでは、buildメソッドでScaffoldインスタンスを返しています。

このScaffoldでは、appBarとbodyにそれぞれAppBarとTextを指定しています。

これによりアプリケーションバーとテキストが表示された画面が作成されます。

StatelessWidgetからStatefulWidgetへ値を渡す

ここではもう一つ新しい処理を行なっています。

それはアプリケーションの土台となっているStatelessWidgetからStatefulWidgetへ値を渡すということです。

StatelessWidgetクラスであるMyAppクラスでは、以下の値が用意されています。

finalが指定されており、値が変更されないことがわかります。

StatelessWidgetでは、このように固定された値を使います。

これらの値をStatefulWidget側に渡して利用しています。

homeに設定するMyHomePageインスタンスを作成する際、titleとmessageという二つの値を用意し、それぞれthis.titleとthis.messageを指定しています。

先ほどのプロパティを引数に指定してMyHomePageインスタンスを作っているのです。

このMyHomePageクラスでは以下のようにコンストラクタが用意されています。

このクラスでもやはり、titleとmessageというプロパティが用意されています。

引数で渡された値が、そのままthis.titleとthis.messageに代入されていることがわかります。

これでMyAppに用意された値が、そのままMyHomePageに渡されました。

MyHomePageから_MyHomePageStateへ

続いて、MyHomePageに保管したtitleとmessageを使って、ステートクラスである_MyHomePageStateインスタンスを作成するところを見ていきましょう。

buildでScaffoldインスタンスを作成している処理は以下のようになります。

Textの引数に、それぞれwidget.titleとwidget.messageを指定しています。

widgetはステートクラスに用意されているプロパティで、このステートが設定されているウィジェット(ここではMyHomePageクラス)のインスタンスが代入されています。

つまりwidget.titleとすることで、この_MyHomePageStateに組み込まれている、MyHomePageのtitleプロパティを取り出しているのです。

これでMyHomePageに用意された値が、_MyHomePageState内で使用できるようになりました。


FlotingActionButtonをタップする

StatefulWidgetの基本がわかったところで、実際に操作してステートを変更してみましょう。

先ほどのサンプルをさらに修正して、タップして表示を変更するサンプルを掲載します。

実行すると以下の画像のように表示されます。

ボタンをタップするとメッセージの表示が変更されました!!

ごく単純なものですが、ユーザーの操作でステートが変更される例として最低限なものは揃っています。

ステート更新とsetState

ステートの変更は、State継承クラス内にメソッドとして用意します。

ここでは、_setMessageというメソッドとして用意しています。

このメソッドでは、setStateというメソッドを実行しています。

このsetStateは、ステートの更新をステートクラスに知らせる働きがあります。

このメソッドに、必要な変更処理を用意しておきます。

このsetStateの引数は関数になっています。この関数内で必要な処理を実行します。

今回のサンプルでは、引数の関数内で_messageプロパティを変更しています。

_MyHomePageStateクラスを見ると、buildで生成されるウィジェットでは、Textのテキストに_messageが指定されています。

_messageを変更することで、更新時にbuildが再実行され、Textの値が変わるようになっています。

FloatingActionButtonについて

この_setMessageは、_MyHomePageStateクラスのfloatingActionButtonという値で呼び出されています。

floatingActionButtonはフローティングアクションボタンを設定します。

フローティングアクションボタンとは、Androidアプリなどでよく見られる、丸いアイコンを表示したボタンのことです。

先ほどのサンプルで、右下に表示された★マークのアイコンがこれです。

このフローティングアクションボタンは、他のウィジェットの配置とは関係なく、常に決まった場所(画面の右下あたり)に表示されます。

フローティングアクションボタンは、FloatingActionButtonというクラスとして用意されています。

サンプルでは、floatingActionButtonは以下のような値が設定されています。

FloatingActionButtonのインスタンスを作成する際には、さまざまな値を引数に用意しておくことができます。

ここでは以下のような値を用意してあります。

onPressed

ボタンをタップした時の処理を指定する。通常、割り当てるメソッド名を指定する。ここでは、_setMessageを指定している。

tooltip

ツールチップとして表示するテキストを指定する。

child

このウィジェット内に組み込まれているウィジェット類をまとめたもの。ここでは表示するアイコンをIconで用意してある。

FloatingActionButtonインスタンスを作成する際には、匿名クラスの要素として、これらの値を用意しておきます。

これらの中で重要なのは、onPressedです。

これはステート変更を行うメソッド名を指定します。

onPressedはイベント処理を設定するためのプロパティです。

ボタンをタップすると、onPressedというイベントが発生し、このイベント発生元のウィジェットにonPressedプロパティが用意されていれば、そこにあるメソッドを呼び出して実行します。

イベントはonPressedだけでなく、他にもさまざまな操作に応じたものが、各ウィジェットに用意されています。ウィジェットを操作したときに何かを行わせたいときは、このイベントを利用した処理を用意することが基本になります。

childでは、表示するアイコンをIconクラスとして作成し、設定しています。

Iconクラスは、名前の通りアイコンを扱うクラスです。このIconはインスタンス作成時、引数にIconsクラスの値を指定しています。Iconsクラスは、主なアイコンを示す値をプロパティとして用意してまとめたものです。このクラスの中で、使用したいアイコンの値を選んで利用します。

ここでは、Icons.starで★アイコンを表示させています。

FloatingActionButtonには、アイコンを表示するchildと、タップした時の処理を指定するonPressedの二つの値が最低でも必要です。この二つの値さえ用意すれば、比較的簡単に利用することができます。


複雑な値の利用

ここまでは、ごく単純なテキストを表示するだけでしたが、より複雑な値を扱うこともあります。

Dataというクラスを定義し、これを値として扱うサンプルを見ていきましょう。

ベースとなるMyAppクラスは全く同じなので省略し、MyHomePageクラス以降を掲載しておきます。

ここでは、_MyHomePageStateクラスにDataリストを保管する_dataプロパティを用意し、ボタンをタップするとDataをランダムに選んで画面に表示します。

Dataクラスについて

複数の値で構成されたデータを扱うクラスとして、Dataクラスを定義してあります。複雑な値を扱う場合、必要な情報をまとめたクラスとして定義して利用するのが一般的です。

Dataクラスでは、_nameと_priceという二つの値を用意しました。コンストラクタでは、引数の値をそれぞれのプロパティに設定できるようにしています。

またtoStringをオーバーライドし、内容をテキストにまとめて設定できるようにしています。

Dataインスタンスの設定

ステートクラス側では、Dataインスタンスをまとめたリストを作っておき、これをランダムに選んで表示させる処理をしています。まず最初にデータとなるリストと、選んだデータを保管するプロパティを用意していきます。

Dataインスタンスを保管する_dataは、あとでデータを改変することがないため、static finalにしてあります。

そして、_dataの最初の項目を_itemに設定しています。

これで起動時に、最初のデータが表示されるようになります。あとは、ステートを設定する_setDataで、リストからランダムに選ぶ処理を用意するだけです。

ここでは、setState内で(_data..shuffle()).firstという形で値を取り出しています。

shuffleはリストの項目をランダムに入れ替えるメソッドで、firstは最初の項目のプロパティです。これにより、_dataからランダムに値を一つだけ取り出せます。


まとめ

今回はステートを使って動的に値を変更することができる、StatefulWidgetについて解説していきました!!

いかがだったでしょうか。

実際に画面に表示するテキストが変わっていくのは見ていて面白いですよね!!

次回はFlutterのレイアウトの続きを公式ドキュメントを元に解説していきたいと思います。

良きFlutterライフを!!

2025-03-21

0件のコメント

コメントはまだありません。最初の一人になりましょう!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です