go_routerの実践活用!Flutterアプリ開発でのルーティング管理テクニック

Flutterアプリ開発でルーティング管理を効率的に行いたいですよね。

この記事では、go_routerを活用したルーティング管理テクニックを解説していきます。

目次

go_router入門: 基本的な使い方を理解しよう

Flutterプロジェクトへのgo_routerの導入方法

Flutterプロジェクトへのgo_routerの導入方法を解説します。

go_routerは、Flutterでアプリケーションのルーティングを効率的に管理するためのライブラリです。以下の手順に従って、go_routerをプロジェクトに追加しましょう。

まず、pubspec.yamlファイルを開き、dependenciesセクションにgo_routerを追加します。最新のバージョンを確認するため、Pub.devを参照してください。

dependencies:
  flutter:
    sdk: flutter
  go_router: ^最新のバージョン

追加したら、ターミナルでflutter pub getコマンドを実行して、go_routerをプロジェクトにインストールします。

次に、プロジェクトのlibフォルダ内に、go_routerの設定を記述するファイル(例:router.dart)を作成します。このファイルには、アプリケーションのルート(ページ)とその設定を定義します。

router.dartファイルに以下のようなコードを記述して、go_routerのインスタンスとルート設定を定義します。

import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart';
import 'package:your_app/screens/home_screen.dart';
import 'package:your_app/screens/about_screen.dart';

final goRouter = GoRouter(
  routes: [
    GoRoute(
        path: '/',
        pageBuilder: (context, state) {
          return MaterialPage(child: HomeScreen());
        }),
    GoRoute(
        path: '/about',
        pageBuilder: (context, state) {
          return MaterialPage(child: AboutScreen());
        }),
  ],
);

この例では、2つのページ(HomeScreenとAboutScreen)がルーティング設定されています。

最後に、プロジェクトのmain.dartファイルを編集し、MaterialApp.routerプロパティに先ほど作成したgoRouter.routerを設定します。

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerDelegate: goRouter.routerDelegate,
      routeInformationParser: goRouter.routeInformationParser,
    );
  }
}

これで、Flutterプロジェクトにgo_routerが導入され、ルーティング管理ができるようになりました。次のステップでは、簡単なルーティング設定方法について解説します。

go_routerを使った簡単なルーティング設定

go_routerを使った簡単なルーティング設定を紹介します。これにより、アプリ内でのページ遷移がスムーズに実現できます。以下の手順で、go_routerを使用してルーティングを設定してみましょう。

まず、router.dartファイルに定義されたgoRouterオブジェクトを使用して、アプリ内のボタンやリンクからページ遷移を行います。例として、HomeScreenからAboutScreenへの遷移を実装します。

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

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            goRouter.go(context, '/about');
          },
          child: Text('Go to About'),
        ),
      ),
    );
  }
}

上記のコードでは、ElevatedButtonのonPressedイベント内で、goRouter.goメソッドを使用して/aboutへ遷移しています。

同様に、AboutScreenからHomeScreenへ戻るための遷移も実装しましょう。

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

class AboutScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('About')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            goRouter.go(context, '/');
          },
          child: Text('Back to Home'),
        ),
      ),
    );
  }
}

このコードでは、AboutScreen内のElevatedButtonからHomeScreenへ戻る遷移を実装しています。

このように、go_routerを使った簡単なルーティング設定を行うことで、アプリ内のページ遷移が容易に実現できます。更に、go_routerの高度な機能を活用することで、リダイレクトやアクセス制限などの複雑なルーティング管理も可能になります。

go_routerで効率的なルーティング管理のテクニック

リダイレクトを活用したスムーズな遷移の実現

リダイレクトは、ユーザーが特定のページにアクセスしようとすると、別のページに自動的に遷移させる機能です。go_routerを使ってリダイレクトを実装することで、アプリ内のページ遷移をより柔軟に制御できます。リダイレクトの基本的な使い方を紹介します。

まず、router.dartファイルにリダイレクト用のGoRouteを追加します。redirectプロパティを使ってリダイレクト先のパスを指定します。

import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart';
import 'package:your_app/screens/home_screen.dart';
import 'package:your_app/screens/about_screen.dart';
import 'package:your_app/screens/secret_screen.dart';

final goRouter = GoRouter(
  routes: [
    // 既存のルート設定
    GoRoute(
        path: '/',
        pageBuilder: (context, state) {
          return MaterialPage(child: HomeScreen());
        }),
    GoRoute(
        path: '/about',
        pageBuilder: (context, state) {
          return MaterialPage(child: AboutScreen());
        }),
    // リダイレクト用のルート設定
    GoRoute(
        path: '/redirect-to-secret',
        redirect: (state) {
          return '/secret';
        }),
    // リダイレクト先のルート設定
    GoRoute(
        path: '/secret',
        pageBuilder: (context, state) {
          return MaterialPage(child: SecretScreen());
        }),
  ],
);

この例では、ユーザーが/redirect-to-secretにアクセスすると、/secretにリダイレクトされます。

次に、アプリ内でリダイレクト用のルートに遷移するボタンを追加しましょう。例として、HomeScreenからリダイレクト先のSecretScreenへ遷移するボタンを実装します。

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

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () {
                goRouter.go(context, '/about');
              },
              child: Text('Go to About'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                goRouter.go(context, '/redirect-to-secret');
              },
              child: Text('Go to Secret via Redirect'),
            ),
          ],
        ),
      ),
    );
  }
}

このコードでは、HomeScreen内にリダイレクト用のボタンを追加し、そのボタンが押されると/redirect-to-secretに遷移し、リダイレクトによってSecretScreenが表示されます。

以上で、go_routerを使ったリダイレクトの基本的な使い方が完了しました。リダイレクト機能を活用することで、アプリ内で条件に応じたページ遷移を実現できます。また、一時的なページ変更やメンテナンス時にリダイレクトを用いることで、ユーザー体験を向上させることができます。

ガードを使ってアクセス制限を実装

ガードは、go_routerで提供されるアクセス制限の機能です。特定の条件が満たされない場合に、ページへのアクセスを制限することができます。リダイレクトと組み合わせることで、より高度なアクセス制御が可能になります。ここでは、ガードの基本的な使い方を紹介します。

まず、auth.dartファイルに以下のようにAuthGuardクラスを作成します。このクラスには、canActivateメソッドがあり、このメソッドがtrueを返す場合にページへのアクセスが許可されます。

import 'package:go_router/go_router.dart';

class Auth {
  bool isLoggedIn = false;

  void login() {
    isLoggedIn = true;
  }

  void logout() {
    isLoggedIn = false;
  }
}

class AuthGuard implements GoRouteGuard {
  AuthGuard(this._auth);

  final Auth _auth;

  @override
  Future<bool> canActivate(GoRouteState state) async {
    return _auth.isLoggedIn;
  }
}

次に、router.dartファイルにガードを適用したいGoRouteguardsプロパティを追加します。また、リダイレクトの設定を削除し、ガードによるアクセス制限に切り替えます。

import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart';
import 'package:your_app/screens/home_screen.dart';
import 'package:your_app/screens/about_screen.dart';
import 'package:your_app/screens/login_screen.dart';
import 'package:your_app/screens/secret_screen.dart';
import 'package:your_app/auth.dart';

final auth = Auth();
final authGuard = AuthGuard(auth);

final goRouter = GoRouter(
  routes: [
    // 既存のルート設定
    GoRoute(
        path: '/',
        pageBuilder: (context, state) {
          return MaterialPage(child: HomeScreen());
        }),
    GoRoute(
        path: '/about',
        pageBuilder: (context, state) {
          return MaterialPage(child: AboutScreen());
        }),
    // ログインページのルート設定
    GoRoute(
        path: '/login',
        pageBuilder: (context, state) {
          return MaterialPage(child: LoginScreen());
        }),
    // ガードを適用したルート設定
    GoRoute(
        path: '/secret',
        guards: [authGuard],
        pageBuilder: (context, state) {
          return MaterialPage(child: SecretScreen());
        }),
  ],
);

ここまでの設定で、ガードが適用された/secretへのアクセスが制限されます。しかし、アクセス制限時のリダイレクト先が設定されていないため、authGuardcanActivateメソッドでリダイレクト先を指定しましょう。

// 既存部分は省略

class AuthGuard implements GoRouteGuard {
  AuthGuard(this._auth);

  final Auth _auth;

  @override
  Future<bool> canActivate(GoRouteState state) async {
    if (_auth.isLoggedIn) {
      return true;
    } else {
      state.goRouter.go(state.context, '/login');
      return false;
    }
  }
}

以上で、ガードを使ってアクセス制限を実現する基本的な設定が完了しました。この設定により、ログインしていないユーザーが/secretにアクセスしようとすると、自動的に/loginにリダイレクトされます。ガードは、特定の条件を満たす必要があるページへのアクセス制限や、アプリ内のアクセス権管理を実現する際に非常に便利な機能です。

さらに、go_routerにはガードだけでなく、リダイレクトや動的ルーティングなどの他の高度な機能も提供されています。これらの機能を組み合わせることで、アプリ内のルーティング管理をより柔軟かつ効率的に行うことができます。

go_routerを使った動的ルーティングの実現

パラメータを活用した動的なページ遷移

パラメータを活用した動的なページ遷移は、アプリ内でより柔軟なルーティング管理を実現するための強力な機能です。go_routerを使用することで、パラメータを簡単に取得・使用することができます。ここでは、記事詳細ページへの遷移を実装する実践例を紹介します。

まず、router.dartファイルに記事詳細ページへのルートを追加します。ここでは、:articleIdというパラメータを設定しています。

import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart';
import 'package:your_app/screens/home_screen.dart';
import 'package:your_app/screens/about_screen.dart';
import 'package:your_app/screens/login_screen.dart';
import 'package:your_app/screens/secret_screen.dart';
import 'package:your_app/screens/admin_screen.dart';
import 'package:your_app/screens/article_screen.dart';
import 'package:your_app/auth.dart';

final auth = Auth();
final authGuard = AuthGuard(auth);

final goRouter = GoRouter(
  routes: [
    // 既存のルート設定
    // 省略

    // 記事詳細ページのルート設定
    GoRoute(
        path: '/article/:articleId',
        pageBuilder: (context, state) {
          final articleId = state.params['articleId'];
          return MaterialPage(
            child: ArticleScreen(articleId: articleId),
          );
        }),
  ],
);

記事詳細ページ(ArticleScreen)を実装します。ここでは、パラメータで渡されたarticleIdを使用して、該当する記事の情報を表示します。

import 'package:flutter/material.dart';

class ArticleScreen extends StatelessWidget {
  final String articleId;

  ArticleScreen({required this.articleId});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Article $articleId')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Welcome to article $articleId!'),
            SizedBox(height: 20),
            Text('Here is the content of article $articleId.'),
          ],
        ),
      ),
    );
  }
}

それでは、HomeScreenから記事詳細ページへ遷移するボタンを追加しましょう。

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

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Welcome to the home page!'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                goRouter.go(context, '/article/42');
              },
              child: Text('Go to Article 42'),
            ),
          ],
        ),
      ),
    );
  }
}

以上で、パラメータを活用した動的なページ遷移の実装が完了しました。この例では、HomeScreenからArticleScreenへの遷移を実現し、articleIdというパラメータを渡しています。ArticleScreenでは、渡されたarticleIdを使用して該当する記事の情報を表示しています。

パスワイルドカードを使った柔軟なルーティング設定

パスワイルドカードを使った柔軟なルーティング設定は、URLパターンが多岐にわたるアプリケーションにおいて便利な機能です。go_routerを使用することで、簡単にパスワイルドカードを設定できます。ここでは、カテゴリ別の記事一覧ページを実装する実践例を紹介します。

まず、router.dartファイルにカテゴリ別の記事一覧ページへのルートを追加します。ここでは、*categoryPathというワイルドカードパラメータを設定しています。

import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart';
import 'package:your_app/screens/home_screen.dart';
import 'package:your_app/screens/about_screen.dart';
import 'package:your_app/screens/login_screen.dart';
import 'package:your_app/screens/secret_screen.dart';
import 'package:your_app/screens/admin_screen.dart';
import 'package:your_app/screens/article_screen.dart';
import 'package:your_app/screens/category_screen.dart';
import 'package:your_app/auth.dart';

final auth = Auth();
final authGuard = AuthGuard(auth);
final adminGuard = AdminGuard(auth);

final goRouter = GoRouter(
  routes: [
    // 既存のルート設定
    // 省略

    // カテゴリ別の記事一覧ページのルート設定
    GoRoute(
        path: '/category/*categoryPath',
        pageBuilder: (context, state) {
          final categoryPath = state.params['categoryPath'];
          return MaterialPage(
            child: CategoryScreen(categoryPath: categoryPath),
          );
        }),
  ],
);

カテゴリ別の記事一覧ページ(CategoryScreen)を実装します。ここでは、パラメータで渡されたcategoryPathを使用して、該当するカテゴリの記事一覧を表示します。

import 'package:flutter/material.dart';

class CategoryScreen extends StatelessWidget {
  final String categoryPath;

  CategoryScreen({required this.categoryPath});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Category: $categoryPath')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Welcome to the $categoryPath category!'),
            SizedBox(height: 20),
            Text('Here are the articles in the $categoryPath category.'),
          ],
        ),
      ),
    );
  }
}

次に、HomeScreenからカテゴリ別の記事一覧ページへ遷移するボタンを追加しましょう。

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

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Welcome to the home page!'), 
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                goRouter.go(context, '/category/technology');
              },
              child: Text('Go to Technology Articles'),
            ),
            SizedBox(height: 10),
            ElevatedButton(
              onPressed: () {
                goRouter.go(context, '/category/sports');
              },
              child: Text('Go to Sports Articles'),
            ),
         ],
       ),
     ),
    );
  }
}

以上で、パスワイルドカードを使った柔軟なルーティング設定の実装が完了しました。この例では、HomeScreenからCategoryScreenへの遷移を実現し、categoryPathというワイルドカードパラメータを渡しています。CategoryScreenでは、渡されたcategoryPathを使用して該当するカテゴリの記事一覧を表示しています。

go_routerを使ったアプリのナビゲーションの最適化

ナビゲーションバーのカスタマイズ方法

ナビゲーションバーのカスタマイズは、アプリの使いやすさや見た目を向上させるために重要な要素です。ここでは、go_routerを使ったナビゲーションバーのカスタマイズ方法を紹介します。

まず、libディレクトリにnavigation_bar.dartという新しいファイルを作成し、カスタムナビゲーションバーを実装します。

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

class CustomNavigationBar extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BottomNavigationBar(
      items: [
        BottomNavigationBarItem(
          icon: Icon(Icons.home),
          label: 'Home',
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.category),
          label: 'Categories',
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.person),
          label: 'Profile',
        ),
      ],
      onTap: (int index) {
        switch (index) {
          case 0:
            goRouter.go(context, '/');
            break;
          case 1:
            goRouter.go(context, '/categories');
            break;
          case 2:
            goRouter.go(context, '/profile');
            break;
          default:
            break;
        }
      },
    );
  }
}

main.dartファイルでCustomNavigationBarScaffoldウィジェットに追加します。

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerDelegate: goRouter.routerDelegate,
      routeInformationParser: goRouter.routeInformationParser,
    );
  }
}

class ScaffoldWithNavigationBar extends StatelessWidget {
  final Widget body;

  ScaffoldWithNavigationBar({required this.body});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('My App')),
      body: body,
      bottomNavigationBar: CustomNavigationBar(),
    );
  }
}

続いて、router.dartファイルを修正して、各ページでScaffoldWithNavigationBarを使用します。

final goRouter = GoRouter(
  routes: [
    // 既存のルート設定
    // 省略

    // 例: ホームページのルート設定
    GoRoute(
        path: '/',
        pageBuilder: (context, state) {
          return MaterialPage(
            child: ScaffoldWithNavigationBar(body: HomeScreen()),
          );
        }),
    // 他のルート設定も同様に修正
  ],
);

これで、ナビゲーションバーのカスタマイズが完了しました。go_routerを使ってナビゲーションバーを実装することで、アプリ内のページ遷移を簡単かつ効率的に管理できます。

go_routerを使ったアプリ内検索の実装

go_routerを使ったアプリ内検索の実装は、ユーザーが求める情報に素早くアクセスできるようにするために役立ちます。ここでは、検索バーと検索結果ページを用いた実装例を紹介します。

まず、libディレクトリにsearch_bar.dartという新しいファイルを作成し、検索バーを実装します。

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

class SearchBar extends StatefulWidget {
  @override
  _SearchBarState createState() => _SearchBarState();
}

class _SearchBarState extends State<SearchBar> {
  final _searchController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: _searchController,
      decoration: InputDecoration(
        hintText: 'Search...',
        suffixIcon: IconButton(
          onPressed: () {
            final query = _searchController.text;
            goRouter.go(context, '/search?q=$query');
          },
          icon: Icon(Icons.search),
        ),
      ),
    );
  }
}

main.dartファイルでSearchBarAppBarに追加します。

class ScaffoldWithNavigationBar extends StatelessWidget {
  final Widget body;

  ScaffoldWithNavigationBar({required this.body});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('My App'),
        bottom: PreferredSize(
          preferredSize: Size.fromHeight(48.0),
          child: Padding(
            padding: EdgeInsets.all(8.0),
            child: SearchBar(),
          ),
        ),
      ),
      body: body,
      bottomNavigationBar: CustomNavigationBar(),
    );
  }
}

続いて、router.dartファイルに検索結果ページへのルートを追加します。

final goRouter = GoRouter(
  routes: [
    // 既存のルート設定
    // 省略

    // 検索結果ページのルート設定
    GoRoute(
      path: '/search',
      pageBuilder: (context, state) {
        final query = state.queryParams['q'] ?? '';
        return MaterialPage(
          child: ScaffoldWithNavigationBar(body: SearchResultScreen(query: query)),
        );
      },
    ),
  ],
);

検索結果ページ(SearchResultScreen)を実装します。ここでは、渡されたqueryに基づいて検索結果を表示します。

import 'package:flutter/material.dart';

class SearchResultScreen extends StatelessWidget {
  final String query;

  SearchResultScreen({required this.query});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Search Results')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Search results for: $query'),
            SizedBox(height: 20),
            // 検索結果を表示するウィジェットをここに追加
          ],
        ),
      ),
    );
  }
}

以上で、go_routerを使ったアプリ内検索の実装が完了しました。この例では、SearchBarウィジェットをAppBarに配置し、検索クエリを入力して検索ボタンを押すと、検索結果ページ(SearchResultScreen)へ遷移します。SearchResultScreenでは、渡されたqueryに基づいて検索結果を表示するようになっています。

アプリ内検索の実装によって、ユーザーは目的の情報に素早くアクセスできるようになります。また、go_routerを使用してパラメータを活用することで、アプリ内で効率的な検索機能を実現できます。

プログラミングスクールをお探しの方はこちら

フリーランス案件をお探しの方はこちら

エンジニア転職サイトをお探しの方はこちら

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次