Navigation

Baek Dong Hyun·2022년 12월 20일
1

1. page 이동 관련

1. push

페이지 이동

ElevatedButton(
	onPressed: () {
		Navigator.of(context).push(
			MaterialPageRoute(builder: (_) {
				return 이동할 페이지
			})
		);
	},
	child: const Text('push')
)

2. pop

페이지 돌아가기

ElevatedButton(
	onPressed: () {
		Navigator.of(context).pop()
	},
	child: const Text('pop')
)

3. of(context)

여기서 보면 .of(context)를 사용하는데 여기서 of함수는 현재 위젯의 위쪽 방향으로 가장 가까운 위젯을 찾는 함수를 뜻한다.

4. argument

페이지 이동시 값을 넘겨주는 방법이있다.

ElevatedButton(
  onPressed: () {
    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (_) {
          return RouteTwoScreen();
        },
        settings: RouteSettings(arguments: 789)
      )
    );
  },
  child: const Text('Push')
)

MaterialPageRoute 안에 settings 라고 있는데 여기서 argument로 값을 전달할 수 있다.

ElevatedButton(
  onPressed: () {
    Navigator.of(context).pop(456);
  }, 
  child: const Text('pop')
)

이렇게 pop에다가도 값을 넣어 전달 가능하다.

받을 때는

ElevatedButton(
  onPressed: () async {
    final result = await Navigator.of(context).push(
      MaterialPageRoute(builder: (BuildContext context) {
        return RouteOneScreen(number: 123);
      })
    );
    setState(() {
      argumentsNumber = result;
    });

    print(result);
  }, 
  child: const Text('push')
)

이렇게 result에 담아서 받을 수 있고,

final argument = ModalRoute.of(context)!.settings.arguments;

이렇게 ModalRoute로도 받을 수 있다.

2. page route

main.dart에서 home으로 안하고 route로 처리하는 방법도 있다.

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // home: HomeScreen(),
      // home 으로 안하고 routes로 할경우에는 아래처럼 
      // initialRoute를 사용해줘야한다.
      initialRoute: '/',
      routes: {
        '/': (context) => HomeScreen(),
        '/one': (context) => RouteOneScreen(),
        '/two': (context) => RouteTwoScreen(),
        '/three': (context) => RouteThreeScreen()
      },
    );
  }
}

위와같이 페이지 라우팅 처리를 Map 형태로 작성해주면 가능하다. 그리고 initialRoute 를 꼭 처리해줘야한다.

이렇게 작업하고 만약 PageRoute로 이동을 하거나 값을 보낼 때는

ElevatedButton(
  onPressed: () {
    Navigator.of(context).pushNamed('/three', arguments: 999);
  }, 
  child: const Text('push Named')
)

이렇게 페이지 이동할 수 있고 값도 보낼 수 있다.

받을 때도 위와 마찬가지로

Widget build(BuildContext context) {
  final argument = ModalRoute.of(context)!.settings.arguments;
  return Scaffold(
    body: MainLayout(
      title: 'Route Three', 
      children: [
        Text('argument: $argument', textAlign: TextAlign.center),
        ElevatedButton(
          onPressed: () {
            Navigator.of(context).pop();
          }, 
          child: const Text('pop')
        )
      ]
    ),
  );
}

이렇게 받아서 사용하면된다.

3. push , pop 다른 메소드들

1. pushReplacement

이동하는 순서가 원래 [HomeScreen → RouteOne → RouteTwo → RouteThree]

이거였다면 이 순서가 아니라 [HomeScreen → RouteOne → RouteThree]

이렇게 RouteTwo가 Three로 대체된다.

ElevatedButton(
  onPressed: () {
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(builder: (_) => RouteThreeScreen( ))
    );
  },
  child: const Text('push Replacement')
),
ElevatedButton(
  // 이건 위랑 같은데 named로 하는거
  onPressed: () {
    Navigator.of(context).pushReplacementNamed('/three');
  },
  child: const Text('named push Replacement')
),

1. pushAndRemoveUntil

이거쓰면 이동하고 뒤로가기가 안된다. 스와이프로 뒤로가기안되고 app bar 상단에도 뒤로가기 없다.

ElevatedButton(
  onPressed: () {
    Navigator.of(context).pushAndRemoveUntil(
      MaterialPageRoute(builder: (_) => RouteThreeScreen()), 
      // false로 하면 사라지고 true로 하면 다시 생김
      // 거이 여기엔 조건이 들어감
      (route) => false
    );
  }, 
  child: const Text('다 날리는 Push And Remove Until')
),
ElevatedButton(
  onPressed: () {
    Navigator.of(context).pushAndRemoveUntil(
      MaterialPageRoute(builder: (_) => RouteThreeScreen()),
      // 이렇게하면 저 '/' 이거 빼고 나머지 route 다 삭제임
      (route) => route.settings.name == '/'
    );
  }, 
  child: const Text('메인 만 남기는 Push And Remove Until')
),
ElevatedButton(
  // 얘는 위랑 같은건데 named인거
  onPressed: () {
    Navigator.of(context).pushNamedAndRemoveUntil(
      '/three',
      (route) => route.settings.name == '/'
    );
  }, 
  child: const Text('메인 만 남기는 Push Named And Remove Until')
)
profile
안녕하세요.

0개의 댓글