マグネテック備忘録

Flutterアプリ開発の備忘録

【Flutter】go_routerで(複数の)パラメータを渡す


結論

  • 結論:pushNamed or goNamedで遷移して、queryParametersに渡したい変数を文字列として指定すればOK。
  • ほかにも方法があるのかもしれませんが、私は調べてもわかりませんでした。



複数パラメータの渡し方

ページの作成

  • ここでは、idとuser名を引数に持つ以下のコンストラクタを持つStatelessWidgetを作成します。
const Page2({super.key, required this.id, required this.user});



GoRouteのpageBuilderの指定方法

  • page2のGoRouteオブジェクトを用意します。
  • pathだけでなく、nameも指定するようにしましょう(今回はname指定でページ遷移をするため)。
  • state.uri.queryParametersにより、パラメータをMap型で受け取ることができます(参考:queryParameters property - Uri class - dart:core library - Dart API)
GoRoute(
  name: 'page2_name',
  path: '/page2',
  pageBuilder: (context, state) {

    // クエリを取得
    final mp = state.uri.queryParameters;

    // パラメータを取得
    int id = json.decode(mp['id']!);
    String user = mp['user']!;

    // ページを渡す
    return MaterialPage(
      key: state.pageKey,
      child: Page2(id: id, user: user)
    );
  },
),


呼び出し方法

pushで呼び出す(現在の画面の上に表示する)場合は、
context.pushNamed(ページ名', queryParameters: Mapで渡したいパラメータを指定);
とすればよいので、今回の場合は

context.pushNamed('page2_name', queryParameters: {'id':'6', 'user': 'Mike'});

とすればよいです。

一方、ページを完全に遷移する(go)の場合は

context.goNamed('page2_name', queryParameters: {'id':'2', 'user': 'Alice'});

としましょう。



サンプルアプリ

サンプルコード

GoRouterを設定

import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:go_router/go_router.dart';
import 'my_app.dart';
import 'page2.dart';

final goRouter = GoRouter(

  routes: [
    GoRoute(
      path: '/',
      pageBuilder: (context, state) {
        return MaterialPage(
          key: state.pageKey,
          child: const MyApp(),
        );
      },
    ),

    // ページ2
    GoRoute(
      name: 'page2_name',
      path: '/page2',
      pageBuilder: (context, state) {

        // クエリを取得Rou
        final mp = state.uri.queryParameters;

        // パラメータを取得
        int id = json.decode(mp['id']!);
        String user = mp['user']!;

        // ページを渡す
        return MaterialPage(
          key: state.pageKey,
          child: Page2(id: id, user: user)
        );
      },
    ),
  ],
);


main.dart

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

void main() {

  MaterialApp app = MaterialApp.router(
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      routerConfig: goRouter,
  );

  runApp(app);
}


初期ページ

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('MyApp'),
      ),
      
      body: Center(
        child: Column(
          children: <Widget>[

            // pushNamed
            ElevatedButton(
              onPressed: (){
                context.pushNamed('page2_name', queryParameters: {'id':'6', 'user': 'Mike'});
              },
              child: const Text("context.pushNamed('page2_name', queryParameters: {'id':'6', 'user': 'Mike'}) \n→ name指定で現在ページの上にPage1を重ねる")
            ),

            // 余白
            const SizedBox(height: 5),

            // goNamed
            ElevatedButton(
              onPressed: (){
                context.goNamed('page2_name', queryParameters: {'id':'2', 'user': 'Alice'});
              },
              child: const Text("context.goNamed('page2_name', queryParameters: {'id':'2', 'user': 'Alice'}) \n→ name指定でPage2に移動")
            ),
          ],
        ),
      ),
    );
  }
}


パラメータを渡したいページ

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

class Page2 extends StatelessWidget {

  final int id;
  final String user;

  const Page2({super.key, required this.id, required this.user});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text('Page2(id = $id, user = $user)'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            ElevatedButton(
              onPressed: (){
                context.pop();
              },
              child: const Text('context.pop()')
            ),
            ElevatedButton(
              onPressed: (){
                context.go('/');
              },
              child: const Text("context.go('/')")
            ),
          ],
        ),
      ),
    );
  }
}



実行例

初期ページ

  • my_app.dartで指定したページを読み込みます。

my_app

pushNamedをしたとき

  • pushのときは先ほどのページの上に重ねているので、上側の矢印 or pop()で戻れます

pushで移動したとき

goNamedをしたとき

  • goのときはページを上書きしているので、pop()では戻れませんし、上側の矢印もありません

goで移動したとき