Flutterにおける画面遷移

## 対象の方
- チュートリアルを終えた
- 何か簡単なものを作ってみようとしている

チュートリアルのみだと`main.dart`ファイルしか触る機会がないと思うので簡単な画面遷移の方法を紹介していきます。
>参考: [Navigate with named routes](https://flutter.dev/docs/cookbook/navigation/named-routes)

かなり丁寧に公式ドキュメントで説明されているのですぐ理解できると思いますが、英語を読みたくないという方はこの記事を読んでいただけると嬉しいです。

ほとんど公式ドキュメントの翻訳になります。

## はじめに
>To work with named routes, use the Navigator.pushNamed() function. This example replicates the functionality from the original recipe, demonstrating how to use named routes using the following steps:
1. Create two screens.
2. Define the routes.
3. Navigate to the second screen using Navigator.pushNamed().
4. Return to the first screen using Navigator.pop().

routesを動かすにあたり、`Navigator.pushNamed()`関数を使用します。

この例では元のレシピ(https://flutter.dev/docs/cookbook/navigation/navigation-basics)
から機能を複製し、どのようにroutesを使っていくか下記のステップに従って紹介していきます。

1. スクリーンを二つ作る
2. `routes`の定義
3. 二つ目のスクリーンへの遷移
4. 最初のスクリーンへ戻る

## 手順
### スクリーンを二つ作る
はじめに画面遷移をさせるために二つのスクリーンを作成します。`HomeScreen`は`SettingScreen`へ遷移するボタンを含み、`SettingScreen`には`HomeScreen`へ戻るボタンを設置します。

```dart:home.dart
import 'package:flutter/material.dart';

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Screen'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('Launch screen'),
          onPressed: () {
            // ボタンを押した時に、SettingScreenへ遷移します
          },
        ),
      ),
    );
  }
}
```
```dart:setting.dart
import 'package:flutter/material.dart';

class SettingScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Setting Screen"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            // ボタンを押した時に、HomeScreenへ戻ります
          },
          child: Text('Go back!'),
        ),
      ),
    );
  }
}
```

### `routes`の定義
>Next, define the routes by providing additional properties to the MaterialApp constructor: the initialRoute and the routes themselves.

>The initialRoute property defines which route the app should start with. The routes property defines the available named routes and the widgets to build when navigating to those routes.

次は、MaterialApp constructorへ追加のプロパティ(initialRoutesや他のroutesなど)を与えることによってroutesを定義していきます。

initialRouteプロパティはアプリケーションを起動した時にrootとして表示される物を定義します。
routesプロパティはページへ遷移する時にビルドするための利用可能な名前のroutesとwidgetsを定義します。

```dart:main.dart
MaterialApp(
    // アプリケーションを'/'routeからスタート。この場合、HomeScreenからスタート。
  initialRoute: '/',
  routes: {
    // '/'routeに遷移する時にHomeScreen widgetをビルド。
    '/': (context) => HomeScreen(),
    // 同じく'/setting'routeに遷移する時にSettingScreen widgetをビルド。
    '/setting': (context) => SettingScreen(),
  },
);
```

*備考: 他にもページを作成したい場合、下記のようにrouteを増やしていきます。

また、rootを指定する方法に`home: HomeScreen()`もありますが、`initialRoute`を使用する場合は使用しないようにしましょう。

```dart
MaterialApp(
  initialRoute: '/',
  routes: {
    '/': (context) => HomeScreen(),
    '/setting': (context) => SettingScreen(),
    '/login': (context) => LoginScreen(),
    '/chat': (context) => ChatScreen(),
  },
);
```

### 二つ目のスクリーンへの遷移
>With the widgets and routes in place, trigger navigation by using the Navigator.pushNamed() method. This tells Flutter to build the widget defined in the routes table and launch the screen.

widgetとroutesを指定したら、`Navigator.pushNamed()`methodを使用して、遷移させます。

このメソッドはFlutterにroutesとローンチするスクリーン(この場合HomeScreen)の中で定義されたwidgetをビルドさせることを伝えます。

```dart:home.dart
class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Screen'),
      ),
      body: Center(
        child: RaisedButton(
          child: Text('Launch screen'),
          onPressed: () {
　　　　　　　// 追加
            Navigator.pushNamed(context, '/setting');
          },
        ),
      ),
    );
  }
}
```
これで`SettingScreen`へ遷移します。

### 最初のスクリーンへ戻る
`Navigator.pop()`を使用して`HomeScreen`へ戻ります。

```dart:setting.dart
mport 'package:flutter/material.dart';

class SettingScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Setting Screen"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            // 追加
           Navigator.pop(context);
          },
          child: Text('Go back!'),
        ),
      ),
    );
  }
}
```

これで全てのステップが完了です。

## 最後に
Splashページなど戻ることを想定していない遷移をする`Navigator.of(context).pushReplacementNamed`などもあるので他にも遷移方法を知りたい方はこちらを参考にすることをおすすめします。

>[Flutter Doc JP: 画面遷移(Navigator)](https://flutter.ctrnost.com/basic/routing/)

画面遷移の仕組みから丁寧に説明してくれています。