Search
▪️

Navigation & Multiple Screens

Navigator은 Flutter에 있는 스크린을 Navigating할 수 있게 돕는 class이다. Theme과 MediaQuery와 마찬가지로 context를 인자로 받아서 사용한다.
Navigation 시에 Flutter에서의 Page들은 기본적으로 Stack처럼 관리된다. List로써 Stack을 이용하는데 다른 페이지로 이동하면 그 페이지를 List에 추가하고 이동했던 페이지에서 나오면 List에서 제거하는 것이다. 즉, List의 가장 마지막 부분, Stack의 가장 윗 부분만 화면에 보이게 된다. (추가를 push 제거를 pop이라고 생각하면 된다.)
매번 constructor을 통해서 화면 전환 하지 않고, 이름으로 할 수 있게 MaterialApp에 route 속성과 Navigator.pushNamed을 이용하면 편하다. 이걸로 화면 넘길 때, 인자 넘기는게 문제므로 넘어온 화면에서는 final routeArgs = ModalRoute.of(context).settings.arguments를 이용하여 인자를 추출한다.
route에 등록한 routeName들은 dynamic에 생성되므로 미리 생성되지 못하거나 뭔가 이상하게 돌아가는 페이지들에 대해서 대처할 수 있는 페이지가 필요하다. 두 가지 방법이 있다.
onGenerateRoute: (settings) {return MaterialPageRoute(builder: (context) ⇒ page());}
route object를 다 찾아보고 페이지 생성에 문제가 있으면 여기로 오게 된다.
onUnknownRoute (settings) {return MaterialPageRoute(builder: (context) ⇒ page());}
route objet를 다 찾아보고 onGenerateRoute도 다 찾아보고 나서도 페이지 생성에 문제가 있으면 여기로 오게 된다.
보통 페이지 오류를 나타내는 페이지를 나타내는 것이다.
Tab을 추가하는 방법은 총 2가지 방법이 있다.
1.
AppBar 아래에 추가하는 방법
Scaffold를 child로 두고 DefaultTabController로 감싸면 된다.
AppBar의 bottom으로 TabBar를 주고, TabBar아래에 여러 Tab들은 둔다.
initialIndex의 default는 0이다.
length로 tab 개수 정할 수 있다.
Scaffold의 body를 TabBarView로 준다.
2.
Bottom Navigator 추가하는 방법
Scaffold의 bottomNavigationBar를 준다.
bottomNavigationBar에 currentIndex 항목이 있는 이유는 별도의 controller를 두지 않기 때문에 현재 상주하고 있는 페이지를 몰라서 그런 것이고, controller가 없기 때문에 onTap 함수를 구현하여 State의 변화를 인지 시켜야 한다.
Tab에 따라 App Bar 이름을 바꾸고 싶다면 List 타입을 Map으로 변경해서 이용해도 좋다. (이름 뿐 아니라 tab 마다 actions도 다르게 하고 싶다거나 해도 이와 같이 이용하면 좋다.)
Drawer 추가 시 stack 계속 늘어나는 것 메모리 주의해야 함 따라서 pushNamed()가 아닌 pushReplacementNamed()를 써야 한다.
Navigator의 pop이 될 때 안에 인자를 넣어주면, 그 인자를 data로 내보냄 그럼 내보낸건 어디서 받는지? → pop이 된다는 것은 이미 push를 했다는 소리이고 pop이 이뤄지기 전 해당 push를 확인해보면 return 타입이 Future인 것을 알 수 있다. then() 메소드를 통해서 받은 데이터 처리하면 된다.
ModalRoute로 인자 받는 행위는 initState()에서 처리하면 안 된다. 이유는 context 때문이다. context를 받아서 처리하는 ModalRoute를 initState()에서 처리하기에는 너무나도 이른 시기인 것이다. 따라서 didChangeDependencies() 이용한다. (initState이후, build 전에 호출된다. 그리고 state가 바뀔 때마다 호출된다.)
GridView도 ListView처럼 builder 이용 가능하다. 이 때, gridDelegate를 주어야 이용 가능하다.
Navigator.of(context).push(MaterialPageRoute or CupertinoPageRoute)
builder
어떤 위젯이 생성될지
fullscreenDialog
default animation이 있는지 true or false
maintainState
settings
Navigator.of(context).pushNamed(string, arguments: {})
widget. 에서 widget property는 state를 갖기 때문에 build 내에서만 이용이 가능하다.
toggle과 같은 기능을 이용하고 싶다면 <List>.indexWhere을 통해서 index 파악하면 된다. 삭제의 경우, 파악한 index를 이용한 removeAt을 이용한다. 추가는 파악한 index을 이용하여 검색 후 해당 항목 추가하면 된다.
<List>.any를 통해 존재 유무에 대해 bool로 check 가능