🚲

go_routerいらないんじゃないですか?

2022/12/18に公開

ページ遷移のコードを短くする

私、最近流行りのgo_router使ってみようと思ったのですが、updateされるたびに破壊的な変更があるのと、ライブラリに頼りすぎない人がいるのをみて、できるだけサポートが続いている安定している物だけ使うようにしてます。
FlutterとDartのコードだけで画面遷移のコードを短く書けて使いませる便利な書き方を見つけたのでやってみました。

本来の書き方はこれ👇

// Within the `FirstRoute` widget
onPressed: () {
  Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => const SecondRoute()),
  );
}

個人開発で使ったのですが、書くの大変でした😅
今度からは、この書き方を参考にしようと思います。

で、今回使うのはこのコード👇

ElevatedButton(
  onPressed: () {
    context.to(const NextPage());
  },
child: Text('次のページへ')),

短いですね...
どうやって作るのか?

Twitterで画面遷移の面白い記事を見つけて、興味があって使ってみたら結構便利だったので、自分用のリファレンスアプリを作ってみました。
こちらが参考にした記事
https://qiita.com/taisuke_k/items/8698fd32f1435d20b5bf?utm_campaign=post_article&utm_medium=twitter&utm_source=twitter_share

taisuke_kさんはOutputされていて、ZennとQiita両方の記事を書かれているようですね。

今回作成したデモアプリ

ディレクトリ構造はこんな風にしました。札幌の知り合いのcondoさんは、monoさんの作ったものを参考にされているそうで私も今回参考にしてみました。

  • ディレクトリ構成
    • 画面はpagesに配置.
    • 拡張機能はextensionに配置.
lib
├── extension
│   └── extension.dart
├── main.dart
└── pages
    ├── home_page.dart
    ├── main_page.dart
    └── next_page.dart

アプリを実行するmain.dart

main.dart
import 'package:flutter/material.dart';
import 'package:page_router/pages/home_page.dart';

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

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

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const HomePage(),
    );
  }
}

画面遷移のコードを短くして、使い回せるコード。
go_routerだと、何処のページへ移動するのか予め定義しておいて、context.goとか短く書けるんですけど、苦い経験がありまして使いたくない😅

extension/extension.dart
import 'package:flutter/material.dart';

/// [extensionで画面遷移のWidgetを作成する関数を作成]
extension BuildContextE on BuildContext {
  Future<void> to(Widget view) async {
    await Navigator.of(this).push(
      MaterialPageRoute(
        builder: (context) {
          return view;
        },
      ),
    );
  }
}

最初のページと画面遷移先のページのコード

最初のページ。
こちらから、画面遷移を行います。

page/home_page.dart
import 'package:flutter/material.dart';
import 'package:page_router/extension/extension.dart';
import 'package:page_router/pages/main_page.dart';
import 'package:page_router/pages/next_page.dart';

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

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('HOME'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
                onPressed: () {
                  context.to(const NextPage());
                },
                child: Text('次のページへ')),
            SizedBox(height: 20),
            ElevatedButton(
                onPressed: () {
                  context.to(const MainPage());
                },
                child: Text('メインページへ')),
          ],
        ),
      ),
    );
  }
}

NextPageへ移動するコード

page/next_page.dart
import 'package:flutter/material.dart';

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

  
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('NEXT'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('次のページです'),
            ],
          ),
        ));
  }
}

MainPageページへ移動するコード

page/next_page.dart
import 'package:flutter/material.dart';

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

  
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('MAIN'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('メインページです'),
            ],
          ),
        ));
  }
}

やってみた感想

今時の技術ってどんどん新しいpackageが出てきたり、進化するのが速くてキャッチアップするのが大変です。
今まで使ってた便利なものがある日使えなくなるかもと、考えると自作できるものは自分で作りたいですね。
リスクヘッジってやつがビジネスの世界では必要ですよね。

Discussion