🔷

【Flutter】 go_routerの使い方

2023/08/22に公開

go_routerとは

  • 画面遷移パッケージ。
  • Navigator → Navigator2.0になった。だがNavigation2.0は複雑で扱いにくい。それを使いやすくしたのがgo_router。
  • go_routerの機能を一言で説明すると「パスと画面の組み合わせを決める」。

go_routerを使用するための下準備

下準備手順
  • パッケージのインストール
  • routerを定義
  • MaterialAppを以下のように書き換え
  • パッケージのインストール
pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
   go_router: ^10.0.0
  • routerを定義
    • パスと画面の組み合わせを定義
    • builderpageBuilderの違い
      • 画面遷移時にアニメーションさせたい場合は、builderpageBuilderに変える。
router.dart
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

final goRouter = GoRouter(
  // アプリが起動した時
  initialLocation: '/',
  // パスと画面の組み合わせ
  routes: [
    GoRoute(
      path: '/',
      name: 'initial',
      pageBuilder: (context, state) {
        return MaterialPage(
          key: state.pageKey,
          child: const MyHomePage(),
        );
      },
    ),
    // ex) アカウント画面
    GoRoute(
      path: '/account',
      name: 'account',
      pageBuilder: (context, state) {
        return MaterialPage(
          key: state.pageKey,
          child: const AccountScreen(),
        );
      },
    ),
    // ex) アカウント詳細画面
    GoRoute(
      path: '/account-detail',
      name: 'accountDetail',
      pageBuilder: (context, state) {
        return MaterialPage(
          key: state.pageKey,
          child: AccountDetailScreen(state.extra as User),
        );
      },
    ),
  ],
  // 遷移ページがないなどのエラーが発生した時に、このページに行く
  errorPageBuilder: (context, state) => MaterialPage(
    key: state.pageKey,
    child: Scaffold(
      body: Center(
        child: Text(state.error.toString()),
      ),
    ),
  ),
);
  • MaterialAppを以下のように書き換え
main.dart
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerDelegate: goRouter.routerDelegate,
      routeInformationParser: goRouter.routeInformationParser,
      routeInformationProvider: goRouter.routeInformationProvider,

      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.orange,
      ),
      // home: const AccoutScreen(),
    );
  }
}

下準備は以上です。

使用例

  • 通常の画面遷移
main.dart
ElevatedButton(
  child: Text("アカウント詳細画面へ遷移"),
  onPressed: () {
    context.push('/account-detail');
  },
),
  • 前の画面へ戻る
accout_detail_screen.dart
ElevatedButton(
  child: Text("アカウント画面へ戻る"),
  onPressed: () {
    context.pop();
  },
),
  • routerのnameプロパティに定義したものを引数にして画面遷移する
main.dart
ElevatedButton(
  child: Text("nameプロパティを引数にしてアカウント詳細画面へ遷移"),
  onPressed: () {
    context.goNamed('accountDetail');
  },
),

画面遷移

  • context.push('/path-name')で次の画面へ。
  • context.pop()で戻る。
  • context.go('/path-name')で画面の順番を飛び越えて、一気に別の画面に行ける。
    • ex) 3つ前の画面に戻りたい時などに使用。
    • context.go()を使用した場合、左上の戻るボタンは表示されない
  • context.goNamed('name')を使用する場合はnameで定義したルーティングの名前を引数に指定する。

次ページへの値の渡し方

  • extra引数で次のページに値を渡すことができる。
main.dart
ListTile(
  onTap: () {
    context.push('/accout-detail', extra: userObject);
  },
);
router.dart
// アカウント詳細ページ
GoRoute(
  path: '/account-detail',
  name: 'accountDetail',
  pageBuilder: (context, state) {
    return MaterialPage(
      key: state.pageKey,
      child: AccountDetailScreen(state.extra as User),
    );
  },
),

参照

(最後にソッといいねボタンやバッジを贈るボタンを押して頂けたら幸いですm(_ _)m)

Discussion