Friday, July 14, 2023

Flutter Navigator 2.0の理解

Flutter Navigator 2.0の紹介

この記事では、Flutterでのページ遷移とアプリの状態管理を実装する新しいAPI、Navigator 2.0について紹介します。従来のNavigator APIは、アプリをナビゲートするためにドキュメントベースのルートを使用していましたが、新しいNavigator 2.0は、宣言型フレームワークを使用してより明確で管理しやすいナビゲーション体験を提供します。

Navigator 2.0の主な改善点

  • より複雑なナビゲーションシナリオに適した宣言型フレームワーク
  • アダプターと異なるページのための動的マッピング機能
  • Webとモバイル用に調整されたルーティング方法
  • 新しいMaterialApp.routerとRouterウィジェットの導入

Navigator 2.0と従来のNavigatorの違い

Navigator 2.0は、ページのパスを指定するための宣言型フレームワークを使用しています。これにより、アプリの状態管理に直接的な影響を与えることができ、特にWebでは、より馴染み深いルーティング手法を提供します。

Navigator.push()とNavigator.pop()の使用例

Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => const DetailScreen()),
);

Navigator.pop(context);

一方、Navigator 2.0では、新たに導入されたRouterとMaterialApp.routerウィジェットを以下のように使用できます。

MaterialApp.router(
    routerDelegate: _routerDelegate,
    routeInformationParser: _routeInformationParser,
);

Navigator 2.0の基本構造

Navigator 2.0の基本構造とコンポーネントを理解するために、以下の重要なコンポーネントを見ていきましょう。

  • RouterとRouteInformationParser

    Routerはアプリのナビゲーション状態を維持し、状態変更時に通知を送信します。一方、RouteInformationParserはURLとナビゲーション状態の間で変換を行う抽象クラスです。具体的には、アプリケーションのURLを状態に解析するか、または状態をURLに変換します。

  • RouterDelegate

    RouterDelegateはMaterialApp.routerウィジェット内で使用され、ナビゲーションロジックの設定を担当します。新しいページの追加や既存のページの削除を管理し、ページの変更に適したUIを提供します。

  • Page

    Pageは、現在のアプリ状態に基づいて宣言される不変のルーティング設定クラスです。MaterialApp.routerに提供されるルーティング情報に基づいて動作し、Routesを作成するビルダーとして機能します。

  • ページ作成用のBuilder Delegates

    Navigator 2.0では、Builder Delegatesがページスタックの管理に使用されます。これらのビルダーは、リストを使用してページの階層を定義し、状態に応じたページ構造を適用してレンダリングします。これにより、動的なレイアウト変更を処理することが可能になります。

アプリ開発への適用

Navigator 2.0の基本構造をアプリ開発プロセスに適用するには、MaterialAppクラスをMaterialApp.routerに置き換え、RouterDelegateとRouteInformationParserを一緒に使用する必要があります。以下の例を参照してください。

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerDelegate: MyRouterDelegate(),
      routeInformationParser: MyRouteInformationParser(),
    );
  }
}

上記のコードでは、MyRouterDelegateおよびMyRouteInformationParserクラスをユーザーが実装する必要があります。

Navigator 2.0でのページとルーターの使用

このセクションでは、Navigator 2.0でのページとルーターの使用について詳しく説明します。これらのコンポーネントを使用してシンプルなナビゲーションフローを構築する方法についても説明します。

ページの使用

Pageクラスは、Navigator 2.0でのRouteを作成するための設定オブジェクトです。このクラスは不変であり、RouterDelegateによって管理されます。Pageは、MaterialPageRouteまたはMaterialPageクラスを使用してナビゲーションスタックに追加されます。以下は、Page定義の作成方法の例です:

MaterialPage(
    key: ValueKey('BooksListPage'),
    child: BooksListScreen(
        books: books,
        onTap: _handleBookTapped,
    ),
);

上記の方法でPageを作成することで、アプリケーションの異なる状態が異なるUI構造で表現されるように定義されます。

UrlStrategyの設定

Webベースのアプリケーションの場合、Navigator 2.0で正しいURLの処理を行うためにUrlStrategyを設定することが重要です。パスベースのURL戦略やハッシュベースのURL戦略など、さまざまなURL戦略を適用できます。URL戦略を設定するには、次のコードをアプリケーションのmain関数に追加します:

import 'package:flutter_web_plugins/flutter_web_plugins.dart';

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

RouterDelegateの実装

RouterDelegateは、Navigator 2.0の主要なコンポーネントであり、現在のアプリケーションの状態に基づいて適切なUIを構築し、ナビゲーションスタックを管理する責任があります。カスタムのRouterDelegateを作成するには、RouterDelegateクラスを拡張し、build、setInitialRoutePath、setNewRoutePath、getCurrentConfigurationなどの必要なメソッドを実装する必要があります。

RouterDelegateのサンプル実装は次のようになります:

class MyRouterDelegate extends RouterDelegate<MyRoutePath>
    with ChangeNotifier, PopNavigatorRouterDelegateMixin<MyRoutePath> {
  ...
}

Navigator 2.0での新しいルートの追加と処理

このセクションでは、Navigator 2.0で新しいルートを追加し、それらを処理する方法について説明します。アプリ内でダイナミックなナビゲーションを実装するには、アプリケーションの状態に基づいてページを追加または削除する必要があります。

ナビゲーションスタックの操作

Navigator 2.0では、ナビゲーションスタックはPageオブジェクトのリストで表され、各Pageオブジェクトはそれぞれ異なるルートを表します。スタックの操作は、アプリケーションの状態に応じてページを追加または削除することから構成されます。

以下は、簡単なナビゲーションスタックの例です:

List<Page> pages = [  MaterialPage(      key: ValueKey('HomePage'),      child: HomeScreen()  ),  if (isDetailsPageShown) // isDetailsPageShownはアプリケーションの状態を表すブール値です    MaterialPage(        key: ValueKey('DetailsPage'),        child: DetailsScreen()    ),];

このコード片では、HomeScreenとDetailsScreenを持つナビゲーションスタックが示されており、DetailsScreenはisDetailsPageShown変数がtrueの場合にのみ表示されます。

新しいルートの処理

Navigator 2.0では、Navigator.push()やNavigator.pop()メソッドを使用するのではなく、前述のセクションで示されたように、ナビゲーションスタックを管理し、適切にアプリケーションの状態を更新する必要があります。これには、ユーザーアクション(ボタンクリックなど)を監視し、応答してアプリケーションの状態を変更することが含まれます。

たとえば、ユーザーがDetailsPageに移動するためのボタンをクリックすると、以下のような関数を実装してアプリケーションの状態を変更できます:

void _handleDetailsPageButtonClicked() {
  // DetailsPageを表示するためにアプリケーションの状態を変更する
  isDetailsPageShown = true;
  
  // RouterDelegateにアプリケーションの状態が変更されたことを通知する
  notifyListeners();
}

逆に、ユーザーが戻るボタンをクリックした場合、DetailsPageをナビゲーションスタックから削除する関数を実装します。

void _handleBackButtonClicked() {
  // DetailsPageを非表示にするためにアプリケーションの状態を変更する
  isDetailsPageShown = false;

  notifyListeners();
}

上記のような関数を実装することにより、ナビゲーションスタックを動的に変更し、ユーザーにシームレスなナビゲーション体験を提供しながら、アプリケーションの状態を適切に保つことができます。

RouteInformationParserの実装

RouteInformationParserは、アプリケーションのURLを解析し、その情報をRouterDelegateに渡す役割を果たします。これにより、URLに基づいてアプリケーションの状態を更新し、適切なページを表示することが可能になります。

RouteInformationParserを実装するには、RouteInformationParserクラスを拡張し、parseRouteInformationとrestoreRouteInformationの2つのメソッドを提供する必要があります。parseRouteInformationメソッドは、アプリケーションのURLを解析し、それを基にアプリケーションの状態を更新します。一方、restoreRouteInformationメソッドは、アプリケーションの状態を基にURLを生成します。

RouteInformationParserのサンプル実装は次のようになります:

class MyRouteInformationParser extends RouteInformationParser<MyRoutePath> {
  @override
  Future<MyRoutePath> parseRouteInformation(RouteInformation routeInformation) {
    ...
  }

  @override
  RouteInformation restoreRouteInformation(MyRoutePath path) {
    ...
  }
}

まとめ

Navigator 2.0は、Flutterでのナビゲーションを管理するための新しいパラダイムを提供します。RouterとRouteInformationParser、RouterDelegate、Page、およびBuilder Delegatesといったコンポーネントを通じて、より柔軟かつ強力なナビゲーション管理が可能になります。

この記事では、Navigator 2.0の基本的な概念とその動作について説明し、RouteInformationParserとRouterDelegateの実装方法、および新しいルートの追加と処理方法について説明しました。これらの知識を用いて、アプリケーションのナビゲーションを効率的に管理し、ユーザーに最高の体験を提供することができます。

しかし、Navigator 2.0はまだ新しい技術であり、その全ての特性と可能性を理解し、適切に利用するには時間と経験が必要です。この記事がその旅の第一歩となることを願っています。


0 개의 댓글:

Post a Comment