見出し画像

プログラミング初心者が始めるFlutter学習②-2

こんにちは。PHR事業開発部の大岡です。
私の回は、Flutterのソースコードを解説していく形でシリーズ化していますが、早くも終わりが見えなくて心が折れそうです。頑張って書いていくので誰か見てくれたら嬉しいです。。
前回は、Flutterでプロジェクトを作成した時にデフォルトで入力されているカウントアップアプリのソースコードを少しずつ変更して、画面のレイアウトを決めるウィジェットについて説明しました。
今回は、その続きで入力フォームと画面遷移について説明していきます。

・文字の部分を入力フォームに変更、数字の部分を「次へ」ボタンに変更
・入力フォームに文字列を入力して「次へ」ボタンを押すと、違うページに画面遷移して入力した文字列が画面中央に表示されるようにする​

ソースコードはこちらです。
https://github.com/psp-engineer/screen_transition


■文字の部分を入力フォームに変更、数字の部分を「次へ」ボタンに変更

画面上半分のText()ウィジェットをTextFormField()ウィジェットに、
画面下半分のText()ウィジェットをOutlinedButon()ウィジェットに変えます。

      // 画面のメインの部分
     body: Center(
       child: Column(
         mainAxisAlignment: MainAxisAlignment.center,
         children: <Widget>[
           // 画面上半分の
           Expanded(
             flex: 1,
             // 真ん中に位置させる
             child: Align(
               alignment: Alignment.center,
               // 入力フォーム
               child: TextFormField(
                 decoration: const InputDecoration(
                   // 何も入力されていない時に表示するヒントテキスト
                   hintText: 'テキストを入力',
                 ),
                 // 入力される文字が変わるごとに関数_setTextを実行する
                 onChanged: (value) => _setText(value),
               ),
             ),
           ),
           // 画面下半分の
           Expanded(
             flex: 1,
             // 真ん中に位置させる
             child: Align(
               alignment: Alignment.center,
               // 枠線があるボタン
               child: OutlinedButton(
                 // 中の文字
                 child: const Text('次へ'),
                 // ボタンがタップされた時に画面遷移する
                 onPressed: () => Navigator.of(context).push(MaterialPageRoute(builder: (context) {
                   // 遷移先の画面
                   return NextPage(inputText);
                 })),
               ),
             ),
           ),
         ],
       ),
     ),

TextFormField():入力フォームを作れる。onChanged: (入力文字が変わるごとに)やonTap: (タップされたとき)などで、何か特定のアクションがあったときにさせたい動作を関数で指定できる。
OutlinedButon():枠線があるボタンを作れる。onPressed: (タップされたとき)やonLongPress: (長押しされたとき)にさせたい動作を関数で指定できる。

decoration: には、InputDecoration()ウィジェットを設定できます。InputDecoration()の中のhintText: で、入力フォームに何も入力されていない時に表示するヒントテキストを指定できます。今回は「テキストを入力」と表示されるようにします。

画像1

背景色がピンクだと気持ち悪いので白に戻して進めます。

■入力フォームに文字列を入力して「次へ」ボタンを押すと、違うページに画面遷移して入力した文字列が画面中央に表示されるようにする

 まず、画面遷移先のページを作成します。今回はnext_page.dartというファイルを新しく作り、そこにNextPageというクラスを作ります。「次へ」ボタンをタップした時にこのNextPageに画面遷移するようにします。
NextPageクラスのコードです。

import 'package:flutter/material.dart';

class NextPage extends StatelessWidget {
 final String inputText;
 const NextPage(this.inputText, {Key? key}) : super(key: key);

 @override
 Widget build(BuildContext context) {
   return Scaffold(
     // ここで背景色を指定
     // backgroundColor: Colors.pink[100],

     // 一番上のタイトルが表示されているところ
     appBar: AppBar(
       title: const Text('Next Page'),
     ),

     // 画面のメインの部分
     body: Align(
       alignment: Alignment.center,
       child: Text(
         // 渡した値を表示する
         inputText,
         // テキストのスタイルを指定できる
         style: const TextStyle(
           // 大きさを20に指定
           fontSize: 20,
         ),
       ),
     ),
   );
 }
}

入力フォームの画面に文字を入力します。

画像2

「NOBORI」と入力しました。次へボタンをタップすると、先ほど新しく作ったNextPage画面に遷移して、画面中央に「NOBORI」と表示されます。

画像3

入力フォームの部分はこのようになっています。

// 入力フォーム
child: TextFormField(
  decoration: const InputDecoration(
    // 何も入力されていない時に表示するヒントテキスト
    hintText: 'テキストを入力',
  ),
  // 入力される文字が変わるごとに関数_setTextを実行する
  onChanged: (value) => _setText(value),
),

decoration: InputDecorationウィジェットを設定することで見た目をカスタムできる。
onChanged: 文字が入力される度に、ここで設定した関数が実行される。

N,O,B,O,R,Iと入力される度に"(value) => _setText(value)"が実行されます。 _setText(value)の中身はこちらです。

  // TextFormFieldに入力された文字列を格納する
 String inputText = '';

 void _setText(String value) {
   // 入力された文字列をinputTextに代入
   setState(() {
     inputText = value;
   });
 }

入力フォームの画面で入力した「NOBORI」という文字列はまず、
"(value) => _setText(value)"のvalueという変数に入ります。しかしこのvalueは、関数"(value) => _setText(value)"の中でしか使えないので、もっと広い範囲で使えるinputTextという変数に_setTextで入れ替えています。画面遷移するときに、そのinputTextをNextPageクラスに値を渡すことで遷移先の画面でも「NOBORI」という文字列を表示することができます。
画面遷移をしている部分はここです。

// ボタンがタップされた時に画面遷移する
onPressed: () => Navigator.of(context).push(MaterialPageRoute(builder: (context) {
   // 遷移先の画面
   return NextPage(inputText);
 })),
),

onPressed: ボタンがタップされたときに行う動作を関数で定義する。
Navigator(): 画面遷移をする。returnで遷移先の画面のクラスを指定する。​

NextPageの引数にinputTextを指定することで、画面遷移する時に一緒にinputTextの値("NOBORI")を渡すことができます。ただ、値は渡しっぱなしではダメで、遷移先の画面で受け取る必要があります。​
NextPageクラスの中の一番最初に

 final String inputText;
 const NextPage(this.inputText, {Key? key}) : super(key: key);

とあります。ここで渡された値を受け取っています。
1行目で受け取った値を入れる変数inputTextを定義して、2行目でNextPage画面を作っています。この2行目のことをコンストラクタといい、コンストラクタでNextPageクラスをインスタンス化しています。

コンストラクタ:クラスをインスタンス化するためのメソッド。引数のthis.inputTextは、渡された値をinputTextに最初から代入しておく、という意味。
インスタンス化:インスタンスとは、実体のこと。クラスを実体にすることをインスタンス化という。今回の例でいうと、NextPageクラスはNextPage画面の設計書。そこから実際の画面を作り出すことをインスタンス化という。

これによって、前の画面で入力された「NOBORI」という文字列をNextPageクラス内でも使うことができるようになりました。
受け取った値を代入したinputTextをText()ウィジェットで表示すれば、NextPageで「NOBORI」と表示できます。
コンストラクタ・インスタンス化については、最初は分からなくてもいいと思います。学習をある程度進めた後に戻って、もう1度調べてみてください。

ようやく1つ目の項目についての説明が終わりました。先は長いですね。。
次は、「データ入力画面を作る」です。
今回作った入力フォーム以外に、ピッカーやラジオボタンなどで複数のデータを入力して、それをアプリ内で保存できるようにします。