今回は、flutterアプリの画面遷移の制御を集約するルーター機能を追加したいと思います。
使用するパッケージ
- 以下のパッケージを使用します。
- 上記リンクの
Readme
には細かい使い方の注意が記載されています。
手順
手順1:ルーター機能のパッケージを追加
私はfvmを導入しているので以下のコマンドでパッケージを追加しました。
fvm flutter pub add go_router
コマンド実行結果
(省略)\training_app> fvm flutter pub add go_router Resolving dependencies... flutter_lints 2.0.3 (3.0.1 available) + go_router 13.0.1 js 0.6.7 (0.7.0 available) lints 2.1.1 (3.0.0 available) + logging 1.2.0 matcher 0.12.16 (0.12.16+1 available) material_color_utilities 0.5.0 (0.8.0 available) meta 1.10.0 (1.11.0 available) path 1.8.3 (1.9.0 available) test_api 0.6.1 (0.7.0 available) web 0.3.0 (0.4.0 available) Changed 2 dependencies! 9 packages have newer versions incompatible with dependency constraints. Try `flutter pub outdated` for more information.
手順2:実装
手順2-1:準備
変更前 | → | コピー | → | リネーム |
---|---|---|---|---|
→ | → |
my_widget2.dart
及びmy_widget3.dart
の中身はmy_widget.dart
と区別がつくように適当に変えておいてください。
手順2-2:router.dart
を作成する
import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:training_app/my_widget.dart'; import 'package:training_app/my_widget2.dart'; import 'package:training_app/my_widget3.dart'; final routerProvider = Provider((ref) => GoRouter( initialLocation: '/my_widget', routes: [ GoRoute( path: '/my_widget', name: 'MyWidget', pageBuilder: (context, state) { return MaterialPage( key: state.pageKey, child: MyWidget(), ); }, ), GoRoute( path: '/my_widget2', name: 'MyWidget2', pageBuilder: (context, state) { return MaterialPage( key: state.pageKey, child: MyWidget2(), ); }, ), GoRoute( path: '/my_widget3', name: 'MyWidget3', pageBuilder: (context, state) { return MaterialPage( key: state.pageKey, child: MyWidget3(), ); }, ), ], errorPageBuilder: (context, state) => MaterialPage( key: state.pageKey, child: Scaffold( body: Center( child: Text(state.error.toString()), ), ), ), ));
手順2-3:main.dart
でルーターをコールする
import 'package:flutter/material.dart'; import 'package:training_app/my_widget.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:training_app/router.dart'; void main() { const app = MyApp(); const scope = ProviderScope(child: app); runApp(scope); } class MyApp extends ConsumerWidget { const MyApp({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { return MaterialApp.router( routerDelegate: ref.watch(routerProvider).routerDelegate, routeInformationParser: ref.watch(routerProvider).routeInformationParser, routeInformationProvider: ref.watch(routerProvider).routeInformationProvider, theme: ThemeData( useMaterial3: true, ), ); } }
手順2-4:my_widget.dart
を修正する
- 画面遷移のトリガーを作る必要があるので、ドロワーメニューから画面を選択する仕様にしてみました。
import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; class MyWidget extends ConsumerWidget { const MyWidget({ super.key, }); @override Widget build(BuildContext context, WidgetRef ref) { final appBar = AppBar( title: const Text('1.タイトル 123456789'), centerTitle: true, titleSpacing:20, titleTextStyle:TextStyle( fontSize: 25, color: Colors.blueGrey, fontWeight: FontWeight.bold, fontStyle: FontStyle.italic, decoration: TextDecoration.underline, ), backgroundColor: Color(0xFFa0d8ef), flexibleSpace: Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/appbar/appbar_bg.png'), fit: BoxFit.fill), ), ), elevation: 3.0, // automaticallyImplyLeading: false, ); final drawer = Drawer( child: ListView( children: <Widget>[ DrawerHeader( decoration: const BoxDecoration( color:Color(0xFFa0d8ef), ), child: Image.asset('assets/images/splash_768x768.png') // child: Text('ドロワーヘッダー') ), ListTile( leading: const Icon(Icons.abc), title: Text('Drawerを表示'), onTap: () { context.pop(); context.push('/my_widget'); }, ), ListTile( leading: const Icon(Icons.access_alarm), title: Text('Drawer2を表示'), onTap: () { context.pop(); context.push('/my_widget2'); }, ), ListTile( leading: const Icon(Icons.copyright), title: Text('Drawer3を表示'), onTap: () { context.pop(); context.push('/my_widget3'); }, ), ], ), ); return Scaffold( appBar: appBar, drawer: drawer, body: Container( child: Text('Bodyを記載しています。'), ), ); } }
my_widget2.dart
、my_widget3.dart
はmy_widget.dart
のコピーをベースにしていますが、画面遷移したことが分かるようにクラス名やタイトルなど一部変更しています。
手順2-5:確認
ドロワーメニューを開く | → | 遷移先ページを指定する | → | 画面遷移が実施される |
---|---|---|---|---|
→ | → |
これでルーター機能の実装は終わりです。
最後に
クローンコードが増えてきたので、そろそろコードの整理を実施したいと思います。