Chapter 05

次の画面に値を渡す

前回の続きです。今回は、画面遷移の時に値を渡す方法を学びましょう!

例えば今回の方法は、ニュースアプリで考えたとき、ニュース一覧からニュース記事詳細画面に遷移するようなケースにおいて活躍します。このケースではニュースのidを詳細画面に渡して、そのidを使って詳細データを取得する、などといった実装が想定されます。

動画としては以下と対応しています!

画面遷移のおさらい

現在は以下のような状態になっていると思います。

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('KBOYのFlutter大学'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('次へ'),
          onPressed: () {
            // ここにボタンを押した時に呼ばれるコードを書く
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => NextPage()),
            );
          },
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }

RaisedButtonのonPressedプロパティの中に、ボタンを押した場合に実行するコードを書いて、次の画面に遷移したところまでが、前回でしたね!

        child: RaisedButton(
          child: Text('次へ'),
          onPressed: () {
            // ここにボタンを押した時に呼ばれるコードを書く
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => NextPage()),
            );
          },
        ),

次は、この画面遷移のコードとNextPageのコードにに少し付け加えて、値を渡せるようにしていきます。

画面遷移のコードで値を渡す

↓このコードを

            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => NextPage()),
            );

↓こうします。まずはイメージをつかんでほしいです。

            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => NextPage('KBOY')),
            );

NextPageの()の中に値を入れます。このカッコのなかに値を入れることで渡せる、という感覚をなんとなくつかんで欲しいです。今回はKBOYという文字列を入れましたが、数字や、classなども渡すことができます。

ただ、現状これだとエラーがでます。NextPageの方を何も変更してないからです。

次はNextPageを変更していきましょう。プラスして、なぜ変更しなければいけないのか、を解説していきます。

イニシャライザを覚えよう

先程、もともとNextPage()としてたところを、NextPage('KBOY')にしましたね。

ここで、そもそもですが、NextPage()というのは、新しいNextPageを作り出しているということを覚えて欲しいです。

例えば

final one = NextPage();
final two = NextPage();

というコードを書いた場合、NextPageというclassの実態はoneとtwoの2つ生み出されます。画面が2つ作られたとイメージすると良いかもしれません。

class NextPage extends StatelessWidget {
  // 省略
}

↑NextPageとして、このように定義されたものを、

NextPage()

とすることで、実態を生み出してるというわけです。人間という定義と、KBOYさんダイゴさんみたいな実在の人間の関係みたいなかんじ、と言ったらわかりやすいですかね?

この実体化することをプログラミング用語で初期化やイニシャライズと言います。そして、イニシャライズするための定義をイニシャライザと言います。

クラスのイニシャライザはデフォルトでは、()のカッコだけですが、(KBOY)のように必ず文字列を渡してイニシャライズしなければならない、というような定義をすることもできます。 次の章ではNextPageのイニシャライザを変更することで、値を渡さないとNextPageが作り出せないという状況にします。

NextPageのイニシャライザを変更

next_page.dartに移動します。

今、next_page.dartのNextPageクラスは以下のようになっていますね。

class NextPage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('KBOYのFlutter大学'),
      ),
      body: Container(
        color: Colors.red,
      ),
    );
  }
}

この1行目と2行目の間にイニシャライザを書くことで、変更できます。

class NextPage extends StatelessWidget {
  // ここにイニシャライザを書く
  

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('KBOYのFlutter大学'),
      ),
      body: Container(
        color: Colors.red,
      ),
    );
  }
}

結論から言うと、こう書きます↓

class NextPage extends StatelessWidget {
  // ここにイニシャライザを書く
  NextPage(this.name);
  String name;

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('KBOYのFlutter大学'),
      ),
      body: Container(
        color: Colors.red,
      ),
    );
  }
}

ここで、

NextPage(this.name);

がイニシャライザで、

String name;

が変数です。受け取ったKBOYという文字列を受け取ると言ったら分かりやすいでしょうか。

ここでやっていることは、nameという変数に文字列を入れるイニシャライザNextPage(this.name)を作った。 ということです。

そもそも、書かなくても、デフォルトで、NextPage()というイニシャライザは定義されています。これを、NextPage(this.name)に書き換えることで、

NextPageを新たに作る時には、文字列を渡さなければ行けなくなりました。

最後に、以下のように、ContainerのchildにTextを追加して、その中身をname変数に指定してあげると、

class NextPage extends StatelessWidget {
  // ここにイニシャライザを書く
  NextPage(this.name);
  String name;

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('KBOYのFlutter大学'),
      ),
      body: Container(
        color: Colors.red,
        child: Text(name),
      ),
    );
  }
}

画面遷移先で、前の画面からもらったKBOYという文字列を表示できます。もちろん、この文字列は前の画面からダイゴを渡せばダイゴと表示されるし、北川景子と渡せばそう表示されます。

(Containerにサイズを指定してないため小ちゃくなりましたがw)

ニュース一覧からニュース記事詳細画面に遷移するようなケースで使えることが想定できましたか?

まとめ

今回の記事は以上です。動画よりもイニシャライザの説明などを丁寧に書いてみました。

動画の方では、次の画面から前の画面に値を渡す方法なども解説しているので、もし良ければ見てみてください。

参考文献

https://www.youtube.com/watch?v=aA8w9Pa7GJU