システム開発部のTです。
前回、画面遷移のアニメーションにふれたかと思います。今回は、画面遷移時に次画面にデータを渡す、または呼び出し元の画面に値を渡すための実装手段について書いていきたいと思います。

以前の記事はFlutter掲載シリーズを参照ください。


本記事の画面構成

本件では、以下の2画面を想定した形で、実装内容を掲載していこうと思います。アプリ起動時、FirstPageが表示される仕様です。

画面間でデータ渡し

Navigator.pushでのデータ渡し

画面遷移の実装については、ここで掲載していますが、
まずは単純にNavigator.push()で画面遷移するときの実装について、
ふれたいと思います。

例として、FirstPageからNextPageを呼ぶときに、NextPageに文字列を渡して、それをNextPageで表示するという簡単な例を記載していこうと思います。

NextPageの実装

こんな感じに実装していきます。

class NextPage extends StatelessWidget {

  // 以下を実装、受け渡し用のプロパティを定義
  final String paramText; 

  // 以下を実装、コンストラクタで値を受領
  NextPage({Key key, @required this.paramText}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('NextPage'),
        centerTitle: true,
      ),
      body: Text(paramText), // ここで受領した値を表示
    );
  }
}

FirstPageの実装

呼び出すときは、Navigator.push()の引数にMaterialPageRouteを設定し、builderのコールバックでNextPageのインスタンスを返すようにします。

こんな感じで。

Navigator.push(context, MaterialPageRoute(builder: (context)=>NextPage(paramText: "任意の文字列")));

上記で、NextPageのparamTextに次画面に渡したい文字列を定義することで、NextPageでは受け渡した値を使用することができます。

いかがでしょうか。
次にNextPageから呼び出し元のFirstPageに戻ったときに値を返す実装を説明します。


Navigator.popでのデータ返し

FirstPageの実装

今度はFirstPageに対して、NextPageから返されたときの受け口を実装します。
以下のNavigator.push()にチェーンしてthenにコールバックを記載し、コールバック内で返却された値を受けます。

Navigator.push(context, MaterialPageRoute(builder: (context)=>NextPage(paramText: ”...”))).then((result) => {
    print(result);
});

NextPageの実装

そして、NextPageでは、Navigator.pop()の引数に返したい値を設定することで、実現できます。

Navigator.pop("任意の返したい値");

Navigator.pushNamedでのデータ渡し

こちらも以下の実装でデータの受け渡しを可能にします。

Navigator.pushNamed(context, "/next", arguments: "任意の値");

ただし、上記で画面を呼び出した場合、呼び出し先では以下の方法でデータを受領することになります。

class NextPage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    // `ModalRoute.of()`メソッドを使用して引数を取得
    final String args = ModalRoute.of(context).settings.arguments;

    return Scaffold(
      body: Center(
        child: Text(args),
      ),
    );
  }
}

また、MaterialAppのonGenerateRouteを実装している場合、settings.argumentsにも引数が設定されます。

class MyApp extends StatelessWidget{

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      initialRoute: '/',
      onGenerateRoute: (settings) {
        print(settings.arguments); // ←引数の取得が可能
        switch(settings.name) {
          case '/': {
            return PageRouteBuilder(
                settings: settings,
                pageBuilder: (_, __, ___)=>FirstPage(),
            );
          }
          case '/next': {
            return PageRouteBuilder(
                settings: settings, // ここでsettingsを設定しておけば、引数の受渡可能
                pageBuilder: (_, __, ___)=>NextPage(paramText: settings.arguments), // これでも可能
            );
          }
          default: {
            return MaterialPageRoute(builder: (context) => FirstPage());
          }
        }
      },
    );
  }
}

まとめ

本件では、画面遷移時の値受け渡しについて記載していきました。
呼び出し先への値渡しの手段については、いくつかパターンがありましたが、呼び出し元へ戻るときの値返しについては、一択かと思います。

本件にて、画面遷移については終了となります。
ご興味ある方は、Flutterでアプリ作ってみていただければと思います。