【Flutter】画面更新【日本語】

Flutterの初歩である画面の更新を自分なりにメモ

Flutterのアプリ作成したときに最初から作成されているカウンターアプリが既に画面更新をしているので、それを元に画面の更新について記載。

オマケで(というかオマケの方が記載量多いけど)Flutterのデモアプリがどのように作成されているのか細かめに説明。

他のプログラミングに関する記事はこちら

スポンサーリンク

画面更新

アプリを作る上で必須である画面更新(動的な画面変更)はFlutter導入時に最初から作成されているカウンターアプリで実装されています。

右下の+ボタンを押すことで、動的に画面の数字が増えていくのがまさに「画面更新」です。

 

そして、ソースコードが以下の通り(英語表記のコメントは全て削除してある)

import 'package:flutter/material.dart';


void main() {
  runApp(MyApp());
}

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

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

  final String title;

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

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

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

 

必要な部分だけをかいつまんで、順を追って説明していきます。

 

まず、動的な画面描写を行うには、Stateクラスを継承したクラス内でsetStateメソッドを使って処理させればいいだけです。

33~37行目の以下部分が該当します。

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

 

_incrementCounterメソッド内でsetStateメソッドを呼び出し、その中で変数「_counter」をインクリメントしてます。

つまり、_incrementCounterメソッドを呼べば変数「_counter」をインクリメントしてから画面更新を行うわけですね(そのまま)

 

 

で、変数「_counter」は52~55行目の以下部分により、画面上に表示されています。

Text(
  '$_counter',
  style: Theme.of(context).textTheme.headline4,
),

 

更に、右下の+ボタン(フローティングアクションボタン)を押すことで_incrementCounterメソッドを呼び出しています。

59~63行目の以下記述が該当する部分です。

floatingActionButton: FloatingActionButton(
  onPressed: _incrementCounter,
  tooltip: 'Increment',
  child: Icon(Icons.add),
),

 

上のソースコードから、onPressed時に_incrementCounterメソッドを呼び出しているのがわかります。

 

ということで、右下の+ボタンが押されることによって画面上に表示させている変数「_counter」がsetStateメソッドによってインクリメントされ、のちに画面が更新されて画面上の数字が増える……という理屈です。

簡単ですね。

スポンサーリンク

オマケ:Flutterのデモアプリを詳細に理解する

画面更新をするだけであればStateクラスを継承したクラスで使えるsetStateメソッド内で何か処理してねというだけで話が終わるのですが、この際だからFlutterのデモアプリについてちょっと細かく調べてみました。

で、調べた内容をコメントにして追加したコードが以下の通り。

import 'package:flutter/material.dart';


void main() {
  // main関数から処理開始.
  // runApp関数でMyAppクラス呼び出し.
  runApp(MyApp());
}

// StatelessWidgetを継承しているMyAppクラス.
// StatelessWidgetを継承することで静的な画面であるという設定になる.
class MyApp extends StatelessWidget {
  // buildメソッドをoverride......つまりは上書きする.
  // buildは色々な条件で起動するメソッド.
  @override
  Widget build(BuildContext context) {
    // build時にはMaterialAppを返す.
    // MaterialAppはアプリケーション全体を管理するもの.
    return MaterialApp(
      // titleはタスクマネージャー上や「最近使ったアプリ」で表示される名称らしくiOSでは使われない情報らしい.
      title: 'Flutter Demo',
      // themeに指定したデータはアプリ全体に適用される.
      theme: ThemeData(
        // primarySwatchは色セットみたいなもの、以下サイト様の説明がわかりやすかった.
        // https://backport.net/blog/2019/07/31/flutter_primary_swatch_custom/
        primarySwatch: Colors.red,
      ),
      // homeに表示させる内容を指定.
      // 引数のtitle変数に'Flutter Demo Home Page'を渡してMyHomePageクラスを呼び出し.
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

// StatefulWidgetを継承しているMyHomePageクラス.
// StatefulWidgetを継承することで動的な画面であるという設定になる.
class MyHomePage extends StatefulWidget {
  // コンストラクタ.
  // Key?の?はオブジェクトがnullかどうかわからない場合に使用するマーク.
  // requiredは値を渡すことが必須なもの.
  // このMyHomePageクラスを生成する際にtitleを渡すことで、勝手に変数のtitle(this.title)に設定してくれる.
  MyHomePage({Key? key, required this.title}) : super(key: key);

  // コンストラクタの処理から引数で渡される'Flutter Demo Home Page'が設定される.
  final String title;

  // createStateメソッドをoverride......つまりは上書きする.
  // createStateはStateクラスのメソッドで状態やら管理してるらしい.
  // アロー関数で指定しているので要はcreateStateメソッドの中身は_MyHomePageStateクラスのコンストラクタと同じ内容だぞ、ってこと.
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

// Stateを継承している_MyHomePageStateクラス.
// MyHomePageStateクラスでcreateStateメソッドの中身はコイツと指定しているのでStateクラスの継承が必要.
// また、createStateとして設定しているクラス名(今回の場合はMyHomePageクラス)をStateのコレクション(<>内のこと)に指定してあげる必要あり.
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  // _incrementCounterメソッド.
  void _incrementCounter() {
    // setStateメソッド内で処理した後に画面の更新を行う.
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    // Scaffoldは画面全体を構成するもの.
    return Scaffold(
      // appBarでアプリバーの設定をする.
      // titleは_MyHomePageStateを使っているMyHomePageのtitleの内容.
      appBar: AppBar(
        title: Text(widget.title),
      ),
      // body内が画面の描写内容.
      // Centerなので左右上下中央寄せ.
      body: Center(
        // Columnなので縦並び.
        child: Column(
          // MainAxisAlignmentでMainAxisAlignment.centerを指定すると中央寄せ.
          // Columnはデフォルトで高さが画面いっぱいになるため、MainAxisAlignment.centerを指定しないと中央寄せにならない.
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            // Column1行目、ただの文字.
            Text(
              'You have pushed the button this many times:',
            ),
            // Column2行目.
            // $で指定すると変数の値を出力できる.
            // Theme.of(context)でThemeで指定したデータを取得できる.
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      // フローティングアクションボタンの設定
      floatingActionButton: FloatingActionButton(
        // onPressedが処理内容.
        onPressed: _incrementCounter,
        // 長押ししたときにでる説明文.
        tooltip: 'Increment',
        // 表示するアイコン
        child: Icon(Icons.add),
      ),
    );
  }
}

 

継承するStateクラスのコレクションの指定方法だとか、MyHomePageクラスのコンストラクタの記述の部分(以下コード)だとか、調べていて実に興味深かったです。

MyHomePage({Key? key, required this.title}) : super(key: key);

 

ちなみにフローティングアクションボタンは他記事でまとめたことがあったので、そこまで抵抗なく理解できました。

フローティングアクションボタン(FloatingActionButton)実装

Flutterでフローティングアクションボタン(FloatingActionButton)を作成してみた。 オマケで複数のフローティングアクションボタンを設定する方法もメモ。 他のプログラミングに関する記事はこちら スポン[…]

 

あとはThemeとかColumnとCenterの中央揃えとか、色々試していて面白かったです。

 

Themeは、なんかアプリ全体の色彩をマテリアルカラー(推奨のRGBみたいなもの)を元に着色してくれるっぽい。

例えばblueだと以下みたいな色彩になるけど、

 

primarySwatch: Colors.red,
とかにすると以下みたいな見た目になります(Themeの色を変えただけでアプリバーとかフローティングアクションボタンとか色んな箇所の色が変わる)
後はCenterは画面中央に揃える機能だけど、ColumnのmainAxisAlignment: MainAxisAlignment.centerも中央揃えにするやつなので、違いが何なのか気になっていじってみました。
Centerを外すと以下みたいな見た目になります。
 
なんで左右の中央揃えにならないかというと、Columnがデフォルト設定だと高さが画面いっぱいに設定されるのが原因らしいです。
Columnを中央揃えにしているけど、その中身は知らんよ、ってことなのかな。
ニュアンスだけはなんとなくわかるけど、まぁそんなもんなんだろうなって理解することにしました。
逆に、ColumnのmainAxisAlignment: MainAxisAlignment.centerを外すと以下みたいな見た目になる。
Centerと(高さをデフォルト設定にしている)Columnを合わせて使う場合は、Centerが横軸の中央揃えで、Columnが縦軸の中央揃えになってる印象を受けました。

他のプログラミングに関する記事

プログラミングまとめ

プログラミングに関する記事です。 言語とかツールごとにまとめています。 スポンサーリンク [adcode] Flutter ・簡単導入~サンプルアプリのデバック起動まで ・文字の表示(重ねて[…]

IMG

スポンサーリンク