Navigator(화면이동)

이원석·2023년 11월 21일
0

Flutter

목록 보기
24/46

Navigator

Navigator로 Route들을 관리한다.

Route

Screen이나 page라고 불리는 위젯

Route를 관리하는 위젯

push

다른페이지로 이동
push를 사용하기 위해서는 context와 route가 필요.
route에는 MaterialPageRoute클래스를 사용한다.
MaterialPageRoute는 이동하려는 Screen을 Route로 만들어준다.

Navigator.push(
            context,
            MaterialPageRoute(
              fullscreenDialog: true,
              builder: (context) => DetailScreen(
                title: title,
                thumb: thumb,
                id: id,
              ),
            ));

pop

이전페이지로 이동
pop은 context만 넘겨주면 된다.

Navigator.pop(context);

pushReplacement

현재페이지를 다른페이지로 대체하는 함수.

Navigator.pushReplacement(
  context,
  MaterialPageRoute(
    builder: (context) {
      return RouteSecondScreen();
    },
  ),
);

pushAndRemoveUntil

특정화면으로 이동하고, 기존에 있는 화면 모두 제거

Navigator.pushAndRemoveUntil(
  context,
  MaterialPageRoute(
    builder: (context) {
      return const HomeScreen();
    },
  ),
  (route) => false,
);

popUntil

첫번째 라우트까지 이동하고, 그 외의 화면들은 종료

Navigator.popUntil(
  context,
  (route) {
    return route.isFirst;
  },
)

removeRoute

특정 route를 지우는 기능.
route 스택들을 관리해 줘야함.

  • Navigator.push함수를 호출할 때 만든 MaterialRoute를 Map에 저장
  • removeRoute함수를 호출할 때 Map에 저장해 놓은 route가 있다면 removeRoute를 호출

addRoute함수에서 route 생성, 생성한 route를 routes에 저장.
removeRoute함수에서는 특정 스크린 이름으로 routes변수에 추가된 것이 있다면 저장해 놓은 route를 불러와서 remove함. 그리고 다시 해당 routes의 값은 초기화

Map<String, MaterialPageRoute<dynamic>?> routes = {
  'route_screen': null,
  'route_second_screen': null,
  'route_third_screen': null,
};

void addRoute({required String screen, required Function(MaterialPageRoute route) callback }) {
  MaterialPageRoute? route;
  switch (screen) {
    case 'route_screen':
      route = MaterialPageRoute(builder: (context) => const RouteScreen());
      break;
    case 'route_second_screen':
      route = MaterialPageRoute(builder: (context) => const RouteSecondScreen(text: "stack"));
      break;
    case 'route_third_screen':
      route = MaterialPageRoute(builder: (context) => const RouteThirdScreen());
      break;
  }
  routes[screen] = route;
  callback(route!);
}


void removeRoute(BuildContext context, String screen) {
  if (routes[screen] != null) {
    Navigator.removeRoute(context, routes[screen]!);
    routes[screen] = null;
  }
}

fullcode

import 'package:flutter/material.dart';

Map<String, MaterialPageRoute<dynamic>?> routes = {
  'route_screen': null,
  'route_second_screen': null,
  'route_third_screen': null,
};

void addRoute({
  required String screen,
  required Function(MaterialPageRoute route) callback,
}) {
  MaterialPageRoute? route;
  switch (screen) {
    case 'route_screen':
      route = MaterialPageRoute(builder: (context) => const RouteScreen());
      break;
    case 'route_second_screen':
      route =
          MaterialPageRoute(builder: (context) => const RouteSecondScreen());
      break;
    case 'route_third_screen':
      route = MaterialPageRoute(builder: (context) => const RouteThirdScreen());
      break;
  }
  routes[screen] = route;
  callback(route!);
}

void removeRoute(BuildContext context, String screen) {
  if (routes[screen] != null) {
    Navigator.removeRoute(context, routes[screen]!);
    routes[screen] = null;
  }
}

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

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("RouteScreen"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () {
                addRoute(
                  screen: "route_second_screen",
                  callback: (route) => Navigator.push(context, route),
                );
              },
              child: const Text("Go second"),
            ),
          ],
        ),
      ),
    );
  }
}

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

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("RouteSecondScreen"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () {
                addRoute(
                  screen: "route_third_screen",
                  callback: (route) => Navigator.push(context, route),
                );
              },
              child: const Text("Go third"),
            ),
          ],
        ),
      ),
    );
  }
}

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

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("RouteThirdScreen"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
                onPressed: () {
                  removeRoute(context, "route_second_screen");
                },
                child: const Text("Route secondScreen")),
          ],
        ),
      ),
    );
  }
}

참고
jinhan38

0개의 댓글