わんぱく Flutter! 第三回 ページ移動をしてみよう!

f:id:Akihiro_Kashiwagi:20210416102435j:plain

わんぱく Flutter! 第三回 ページを追加してみよう!

 

 

 

 

 前回は、動作確認用のアプリケーションに、色々な Widget を追加してみました。その他の基本的な動作と言えば、「ページ移動」ではないでしょうか。今回は、ページ移動を行ってみます。 Flutter のページ移動は、前回作成した動作確認用のアプリケーションと同様、新しい xxxx.dart ファイルに、ページを作成する class を記述して、呼び出し元 class から、Navigator.push() API を呼ぶだけです。それでは早速、やって行きましょう。

 

 

1. Navigator.push によるページ移動

 

 まず、新しい xxxx.dart ファイルを作成します。どのような方法でも宜しいのですが、android studio を使っているなら、左ウィンドウの project - lib を右クリックして、new - dart file から "secondpage.dart" を作成します。作成したら、下記コードを記述して下さい。

 

import 'package:flutter/material.dart';

class secondpage extends StatefulWidget {
secondpage({Key key}) : super(key: key);

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

class _secondpage extends State<secondpage> {

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Second Page"),
),
body: Center(
child: Text("")
),
);
}
}


細かい説明は今回は飛ばして、Flutter の新しいページは、このフレームワークで書くのだと理解してください。 class が二つあるのが解ると思います。ひとつ目が、呼び出し側から見た class 名を記述します。そして、ふたつ目の class があると思います。違いは解るでしょうか。 ー

そう、 class 名の頭に "_" が付いています。 前回も簡単に説明してありますが、Flutter は頭に "_" を付けると、外部からは参照できない扱いとなります。

また、よく目立つ "return" の直ぐ下に "appBar:" と言う記述があります。これは、アプリケーションの上に表示されるバーです。これを付けておくと、画面遷移をした後に、戻るボタン "←" が自動的に表示されて便利です。特に理由がなければあって問題ないでしょう。

 

 

f:id:Akihiro_Kashiwagi:20210320153214j:plain

figure 01


そうしたら、呼び出し元である main.dart に、Navigator.push() を追加します。ボタンを押した時にページ移動させたいのですから、ElevatedButton() の onPressed に記述します。大括弧の前に空の括弧があったり、少し妙ちくりんな記述ですが、ここは、こう書くのだと思って下さい。これも、dartシンタックスシュガー(省略した表記法)です。解りにくいですね。

 

ElevatedButton(
child: Text("Next"),
onPressed: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => secondpage()),
);
}
)


Navigator.push() の引数の MaterialPageRoute() にある secondpage() が、今回新しく作ったページの class 名です。そして、新しく作った secondpage.dart を呼び出すのですから、main.dart の先頭にある import に、このファイルを加えておきます。

import 'package:flutter/material.dart';
import 'secondpage.dart';

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


これで準備完了です。android studio を使っているのであれば、文法エラーなどには、赤い波線のアンダーラインが付くので、そこを直してから実行します。実行したら、中央に ElevatedButton() が表示されているはずです。言うまでもなく、そのボタンを押すと、ページ移動するという事です。

 

f:id:Akihiro_Kashiwagi:20210320160942p:plain

figure 02



はい。無事、ページ移動しました。ページを戻る際は、上の appBar の矢印を利用します。

 

 

2. 引数による値渡し

 

 次に必要になってくるのは、恐らく、引数による値渡しでしょう。ページ間で、何らかのデータのやり取りがあるのが普通です。これは、MaterialPageRoute() にある class の引数として渡します。例えば、"メッセージ" という文字列を、次のページの message と言う変数へ渡すなら、以下のように記述します。

 

Navigator.push(
context,
MaterialPageRoute(builder: (context) => secondpage( message: "メッセージ")),
);


そして、受け取り側である secondpage class では、引数として受け取った値を、this.message へ格納することを指定します。

 

import 'package:flutter/material.dart';

class secondpage extends StatefulWidget {
secondpage({Key key, this.message}) : super(key: key);

final String message;

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


これで message を受け取ることができます。確かに受け取ることができたことを確認するために、Text Widget に表示してみましょう。

body: Center(
child: Text( widget.message )
),



受け取った message を、下の class の Text Widget で使うには、上記の通り、widget に属する変数としてアクセスします。ちょっと込み入ってきますので、詳しい説明は後回しにしますが、上の class を、下の class が継承しているので、上の class で受け取った引数は、widget のプロパティとなります。

それでは実行してみましょう。

f:id:Akihiro_Kashiwagi:20210320162606p:plain

figure 03

 

引数が複数ある場合は、カンマで繋げて記述します。

 

class secondpage extends StatefulWidget {
secondpage({Key key, this.message1, this.message2}) : super(key: key);

final String message1;
final String message2;

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



呼び出し側も同様です。


Navigator.push(
context,
MaterialPageRoute(builder: (context) => secondpage( message1: "メッセージ", message2: "メッセージ2")),
);

 

 

3. Global 変数を使用した値の参照


 と、ここまでは行儀のよいプログラムでの、正攻法による値渡しですが、些か面倒です。私は、非常に面倒に感じているので、global 変数を使用することをお薦めします。

例えば、main.dart の先頭、import が記述されている直ぐ下に、プログラム全体で共有したい値を記述しておくと、他の xxxx.dart ファイルで記述している class からも参照することができます。

 

import 'package:flutter/material.dart';
import 'secondpage.dart';

String g_message = "広域メッセージ";

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


これは、dart プログラミング言語における変数の有効範囲(スコープ)を利用した値の共有方法です。ここで、g_message がプログラム全体で共有したい変数です。

 

import 'package:flutter/material.dart';
import 'main.dart';



secondpage.dart の先頭の import にも import 'main.dart'; を追加しておきます。そして、試しに Text Widget で表示させてみて下さい。

body: Center(
child: Text( g_message )
),



flutter の値渡しは、こっちの方がいいんじゃない? とても簡単で、widget.xxxx の記述もいりません。それでは、実行してみましょう。


f:id:Akihiro_Kashiwagi:20210320164850p:plain

figure 04


今回は、ページ移動と、値渡しについて解説しました。

 

以上