banner
MiniKano

MiniKano

This is MiniKano's blog based on Blockchain technology. 新手,请多关照~
github

Flutter ルーティング設定

flutter ルーティング#

** ルーティング (Route)** は WEB 開発のシングルページアプリケーションで非常に一般的で、Flutter にも独自のルーティングがありますが、Android システムでは Route は Activity を指し、IOS システムでは View Controller を指します。
ルーティング管理はルーティングスタックを使用して push と pop の操作を行い、ルートをプッシュおよびポップします。スタックに入れることは新しいページを開くことを意味し、スタックから出ることはページを閉じることを意味します。ルーティングスタックを使用するだけでなく、ルーティングのインターセプトやルーティングのリダイレクトなど、他の操作も必要です。

通常のルーティングとルーティングの遷移#

  1. MyText という新しいルートを作成します(パラメータの受け渡しが可能)。
class MyText extends StatefulWidget {
  //他のページからFormページに遷移して名前付きルートで値を渡す
  final Map arguments;
  const MyText({super.key, required this.arguments});

  @override
  State<MyText> createState() => _MyTextState();
}

class _MyTextState extends State<MyText> {
    
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Route"),
      ),
      body: Center(
        child: Text(widget.arguments.toString()),
      ),
    );
  }
}
  1. 他の任意のウィジェットでこのルートを使用します(事前に import が必要です)。ここでは ElevatedButton を使用してデモを行い、ボタンをクリックすると新しいルートに遷移します(パラメータも渡します)。
//imported
ElevatedButton(
    onPressed: () {
        //ルーティング
        //またはNavigator.push、コンポーネントの状況に応じて
        Navigator.of(context).push(
            MaterialPageRoute(
                builder: (BuildContext context) {
                    return const MyText(
                        arguments: {'kano': "kanokano.cn"},
                    );
                },
            ),
        );
    },
    child: const Text("検索(ルーティング遷移)"),
),

名前付きルートの作成#

注意:名前付きルートは新しい Flutter ドキュメントで使用が推奨されていません

名前付きルートはディープリンクを処理できますが、動作は常に同じでカスタマイズできません。プラットフォームが新しいディープリンクを受信すると、Flutter はユーザーが現在いる場所に関係なく Navigator に新しいルートをプッシュします。

Flutter は名前付きルートを使用するアプリケーションに対してブラウザの進むボタンもサポートしていません。これらの理由から、ほとんどのアプリケーションで名前付きルートの使用を推奨しません。

  1. MyText という新しいルートを作成します(ここでは上記の MyText をそのまま使用します)。

  2. main.dart で Tabs ルートを使用します。

import 'package:flutter/material.dart';
//通常のコンポーネント
import './mytext.dart';

void main(List<String> args) {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "Test",
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),
      //1.ルートを初期化
      initialRoute: '/text1',
      //直接名前付きルート
      routes: {
        '/text1': (context) => const MyText(),
      },
    );
  }
}
  1. ルーティングの遷移
ElevatedButton(
    onPressed: () {
        //ルーティング
        Navigator.pushNamed(context, '/text1');
    },
    child: const Text("基本ルーティング遷移text1"),
),

名前付きルートでのパラメータの受け渡し#

全体的にはこの 3 ステップです:

  1. ルートを設定
  2. ルートを初期化
  3. onGenerateRouter を設定
class MyApp extends StatelessWidget {
  //ルートのパラメータ渡し - 1.ルートを設定(routes.dartとして単独で抽出可能)
  Map routes = {
    "/": (context) => const Tabs(),
    "/news": (context) => const NewsPage(),
    "/search": (context) => const NewsPage(),
    //パラメータ付き
    "/form": (context, {arguments}) {
      return FormPage(
        arguments: arguments,
      );
    },
    "/shop": (context, {arguments}) {
      return ShopPage(arguments: arguments);
    }
  };

  MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: "Test",
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),

      //2.ルートを初期化
      initialRoute: '/',

      //ルートのパラメータ渡し-3.ルートを処理(routes.dartとして単独で抽出可能)
      //onGenerateRouterを設定(これはインターセプターだと思います)
      onGenerateRoute: (RouteSettings settings) {
        print(settings); //ルートのパラメータ情報
        print(settings.arguments); //渡されたパラメータ
        print(settings.name); //ルート名
        final String? name = settings.name;
        final Function? pageCoutentBuilder = routes[name];
        if (pageCoutentBuilder != null) {
          //パラメータありの場合
          if (settings.arguments != null) {
            final Route route = MaterialPageRoute(
              builder: (context) =>
                  pageCoutentBuilder(context, arguments: settings.arguments),
            );
            return route;
          } else {
            //パラメータなしの場合
            final Route route = MaterialPageRoute(
              builder: (context) => pageCoutentBuilder(context),
            );
            return route;
          }
        }
        return null;
      },
    );
  }
}
  1. ルーティングの遷移にパラメータを付けて渡す
ElevatedButton(
    onPressed: () {
        //ルーティング
        Navigator.pushNamed(context, '/form',arguments: {"kano": "kanokano"});
    },
    child: const Text("名前付きルートでのパラメータ渡しform"),
),

上のルートに戻る#

単に次のように使用します。

Navigator.pop(context);
//または
Navigator.of(context).pop()

ルートの置き換え#

一歩一歩戻りたくない場合は、ルートの置き換えモードを使用できます(ページを遷移し、現在のページを破棄します)。

Navigator.of(context).pushReplacementNamed('/xxx')
//または
Navigator.pushReplacementNamed(context,'/xxx')

ルーティングの遷移スタイルの設定#

Material コンポーネントライブラリには、プラットフォームスタイルに一致するルーティング切り替えアニメーションを使用できるMaterialPageRouteコンポーネントが提供されています。iOS では左右にスライドして切り替え、Android では上下にスライドして切り替えます。CupertinoPageRouteは Cupertino コンポーネントライブラリが提供する iOS スタイルのルーティング切り替えコンポーネントで、Android でも左右に切り替えスタイルを使用したい場合はCupertinoPageRouteを使用できます。

  1. インポート
import 'package:flutter/cupertino.dart';
  1. MaterialPageRouteCupertinoPageRouteに変更
// import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_application_1/pages/form.dart';
import 'package:flutter_application_1/pages/news.dart';
import 'package:flutter_application_1/pages/tabs/shop.dart';
import '../pages/tabs.dart';

//ルートのパラメータ渡し - 1.ルートを設定(routes.dartとして単独で抽出可能)
Map routes = {
  "/": (context) => const Tabs(),
  "/news": (context) => const NewsPage(),
  "/search": (context) => const NewsPage(),
  //パラメータ付き
  "/form": (context, {arguments}) {
    return FormPage(
      arguments: arguments,
    );
  },
  "/shop": (context, {arguments}) {
    return ShopPage(arguments: arguments);
  }
};
var onGenerateRoute = (RouteSettings settings) {
  final String? name = settings.name;
  final Function? pageCoutentBuilder = routes[name];
  if (pageCoutentBuilder != null) {
    //パラメータあり
    if (settings.arguments != null) {
      final Route route = CupertinoPageRoute(
        builder: (context) =>
            pageCoutentBuilder(context, arguments: settings.arguments),
      );
      return route;
    } else {
      //パラメータなし
      final Route route = CupertinoPageRoute(
        builder: (context) => pageCoutentBuilder(context),
      );
      return route;
    }
  }
  return null;
};
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。