概要
go_router の公式サンプルを動かす。
また、機能ごとにファイルを分割する。
以下の環境
- Flutter 2.8.1
- go_router 3.0.1
画面遷移ライブラリ gro_router
Flutter で 画面遷移を実現する方法は複数ある。
- Navigator ver1
- Navigator ver2
- go_router ( Navigator ver2 をラッピング )
今回は go_router を利用する。 Navigator ver2 単体では複雑なところをラッピングしてくれて、簡単に扱えるようになっているため。
なんと有志がドキュメントを日本語化してくれている。
チュートリアル
インストール・起動
以下でアプリの雛形作成。
flutter create go_router_sample cd sample flutter pub add go_router
公式の Example を lib/main.dart に貼り付け。
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
void main() => runApp(App());
class App extends StatelessWidget {
App({Key? key}) : super(key: key);
static const title = 'GoRouter Example: Declarative Routes';
@override
Widget build(BuildContext context) => MaterialApp.router(
routeInformationParser: _router.routeInformationParser,
routerDelegate: _router.routerDelegate,
title: title,
);
final _router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) => const Page1Screen(),
),
GoRoute(
path: '/page2',
builder: (context, state) => const Page2Screen(),
),
],
);
}
class Page1Screen extends StatelessWidget {
const Page1Screen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text(App.title)),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () => context.go('/page2'),
child: const Text('Go to page 2'),
),
],
),
),
);
}
class Page2Screen extends StatelessWidget {
const Page2Screen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text(App.title)),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () => context.go('/'),
child: const Text('Go to home page'),
),
],
),
),
);
}
起動確認。
flutter run
初期ページ。「Go to page 2」により2ページ目に遷移する。
2ページ目。「「Go to home page」により、初期ページへ遷移する。
役割ごとにファイル分割
以前カウンターアプリを分割したように、機能ごとにファイルを分割する。
今回は 4 ファイルに分割する。基本、一つのファイルには一つの役割しか持たせないようにする方針。
- main.dart
- app.dart
- page1.dart
- page2.dart
main.dart
main.dart はアプリを実行するための main 関数のみを記述する。
import 'package:flutter/material.dart';
import 'app.dart';
void main() => runApp(App());
app.dart
app.dart では基となる Widge とルーティングを記述する。
build メソッド内で返す Widget が、 MaterialApp から MaterialApp.router に変更
ページ・機能を呼び出すコントロール部分の認識。ただし、ルーティング機能 ( _router ) は別ファイルに分けていく方針。
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'page1.dart';
import 'page2.dart';
class App extends StatelessWidget {
App({Key? key}) : super(key: key);
static const title = 'GoRouter Example: Declarative Routes';
@override
Widget build(BuildContext context) => MaterialApp.router(
routeInformationParser: _router.routeInformationParser,
routerDelegate: _router.routerDelegate,
title: title,
);
final _router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) => const Page1Screen(),
),
GoRoute(
path: '/page2',
builder: (context, state) => const Page2Screen(),
),
],
);
}
page1.dart
初期ページ。
「onPressed: () => context.go(‘/page2’),」が画面遷移部分。
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'app.dart';
class Page1Screen extends StatelessWidget {
const Page1Screen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text(App.title)),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () => context.go('/page2'),
child: const Text('Go to page 2'),
),
],
),
),
);
}
page2.dart
遷移先のページ。
「onPressed: () => context.go(‘/’)」
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'app.dart';
class Page2Screen extends StatelessWidget {
const Page2Screen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text(App.title)),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () => context.go('/'),
child: const Text('Go to home page'),
),
],
),
),
);
}
まとめ
今回のサンプルコードはこちら。
app.dart が大きい。次回は Riverpod を利用して _router を分離していく。
した。
エラー
Because go_router depends on go_router, version solving failed.pub finished with exit code 65
flutter pub add go_router したタイミングで表題のエラー発生。
プロジェクトフォルダ名を「go_router」としていた。
プロジェクトフォルダ名を「go_router_sample」に変更した後、再度 flutter pub add go_router をすると成功。
ライブラリ名とプロジェクトフォルダ名を同名にしてはダメ。
コメント