본문 바로가기

개발(합니다)/Flutter&android&ios

[flutter-10] Navigator : MaterialPageroute, initialRoute

반응형

MaterialPageroute

1. Router 개념

  • 단순히 스마트폰에서 보이는 하나의 페이지나 화면을 의미합니다.

2. Navigator의 정의와 push, pop 함수, stack 자료 구조

  • Navigator의 정의는 모든 앱 페이지를 스택 자료 구조로 Route 객체를 관리하고 있는 기능입니다.
  • Stack은 어떤 물건을 쌓아 올린다는 개념으로 LIFO 후입선출의 자료구조로 나중에 들어온걸 먼저 내보냅니다.
    • 최초 페이지 위에 다음 페이지가 쌓이고 다음 페이지 위에 다다음 페이지가 쌓이는 형태입니다.
    • push : 데이터를 쌓는 기능
    • pop : 데이터를 내보내는 기능

3. MaterialPageroute 위젯과 context

  • return 하는 모든 Scaffold와 같은 위젯이 Router라고 볼 수 있습니다.
  • context를 이용해 위치 정보를 쌓아 올리기 위해 사용합니다.
    • 최초 페이지의 위치를 알기 위해 context를 사용합니다.
  • MyPage1는 Widget tree에 존재하지만 MaterialApp 위젯에서 MyPage2는 호출되지 않아 존재 하지 않습니다.
    • 모든 위젯은 MaterialApp 위젯이 감싸고 있어야 합니다.

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

    main() => runApp(MyApp());

    class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        home: Scaffold(
          body: MyPage1(),
        ),
      );
    }
    }

    class MyPage1 extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("first page"),
          ),
          body: Center(
            child: RaisedButton(
              onPressed: () {},
              child: Text("go to Second page"),
            ),
          ),
        );
      }
    }

      class MyPage2 extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              title: Text("second page"),
            ),
            body: Center(
              child: RaisedButton(
                onPressed: () {},
                child: Text("go to first page"),
              ),
            ),
          );
        }
      }
    ```
  • MaterialPageRoute는 flutter가 기본으로 제공하는 기능으로 builder를 제공하며 라우팅을 하는 과정에서 안전장치로 사용합니다.
  • MaterialPageRoute는 앱상에서 페이지 이동을 할 때 기본 애니메이션이 제공됩니다.
    • android : 페이지 들어갈 때 fade in, 페이지 나갈 때 fade out
    • ios : 좌우로 움직이면서 페이지 이동

4. 페이지 이동 기능 구현 완성

import 'package:flutter/material.dart';

main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: MyPage1(),
      ),
    );
  }
}

class MyPage1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("first page"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.push( // MaterialPageRoute로 안전 장치로 Builder를 사용해 Route기능으로 추가
                context,
                MaterialPageRoute(
                  builder: (context) => MyPage2(),
                ));
          },
          child: Text("go to Second page"),
        ),
      ),
    );
  }
}

class MyPage2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("second page"),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.pop(context); // 사라져야 할 자신
          },
          child: Text("go to first page"),
        ),
      ),
    );
  }
}

  • MyPage2가 추가 됨을 확인 할 수 있습니다.
  • AppBar를 이용하면 자동으로 페이지 뒤로가기 버튼을 만들어줍니다.

flutter에서 언더스코어( _ )를 매개변수로 할 경우 필요 없는, 사용하지 않는 매개변수임을 의미합니다.

MultiPageRoute

  • 각각의 Route에 이름을 지정해주어 이름을 근거해 이동할 Route를 생성해 push로 쌓아주는 방식입니다.
  • MaterialApp의 initialRoute(화면 최초 호출 Route = home, 둘 중 하나만 가능), routes(이동할 페이지의 이름 지정 및 생성)는 MultiPageRoute를 구현할 때 꼭 필요한 요소입니다.
    • Map 자료 구조는 키, 값이 1대 1로 매칭되는 자료 구조입니다.
    • initialRoute의 값은 '/'로 합니다.
    • routes { "/" : (context) => ScreenA(), "/b" : (context) => ScreenB(), "/c" : (context) => ScreenC(), }, 처럼 Map형태로 MaterialPageroute에서 사용했던 방법처럼 작성합니다.
    • Navigator.pushNamed(context, "/b");를 이용해 이동할 named를 입력합니다.

import 'package:flutter/material.dart';

main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // home: ScreenA()  ,
      initialRoute: '/',
      routes: {
        "/" : (context) => ScreenA(),
        "/b" : (context) => ScreenB(),
        "/c" : (context) => ScreenC(),
      },
    );
  }
}


class ScreenA extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("ScreenA"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            RaisedButton(onPressed: () {
              Navigator.pushNamed(context, "/b");
            },
              color: Colors.red,
              child: Text("go to ScreenB"),
            ),
            RaisedButton(onPressed: () {
              Navigator.pushNamed(context, "/c");
            },
              color: Colors.red,
              child: Text("go to ScreenC"),
            )
          ],
        ),
      ),
    );
  }
}




class ScreenB extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("ScreenB"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            RaisedButton(onPressed: () {
              Navigator.pushNamed(context, "/");
            },
              color: Colors.red,
              child: Text("go to ScreenA"),
            ),
            RaisedButton(onPressed: () {
              Navigator.pushNamed(context, "/c");
            },
              color: Colors.red,
              child: Text("go to ScreenC"),
            )
          ],
        ),
      ),
    );
  }
}



class ScreenC extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("ScreenC"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            RaisedButton(onPressed: () {
              Navigator.pushNamed(context, "/");
            },
              color: Colors.red,
              child: Text("go to ScreenA"),
            ),
            RaisedButton(onPressed: () {
              Navigator.pushNamed(context, "/b");
            },
              color: Colors.red,
              child: Text("go to ScreenB"),
            )
          ],
        ),
      ),
    );
  }
}
반응형