본문 바로가기
안드로이드

[안드로이드] 화면 전환 - Navigation

by algosketch 2021. 12. 25.

 이 글은 제가 만든 이 프로젝트를 기반으로 설명하고 있습니다. 제가 만든 오픈소스이니 많은 fork 와 star 부탁드립니다! 해당 프로젝트는 변경될 수 있습니다.

 안드로이드 Navigation 에 대해 알아보자. 참고로 공식문서는 여기에 있다. 안드로이드 공식문서는 영어가 가능하다면 영어로 읽는 편이 좋다. 한글 버전이 영어 버전보다 업데이트가 느리고 번역하면 안 되는 것을 번역해서 오해를 일으키는 단어들이 몇몇 있다.

 안드로이드 Navigation 은 Jetpack 에 포함된 라이브러리이다. nav_graph.xml 을 통해 구조화가 가능하고 화면 구조를 시각적으로도 확인할 수 있다. 아래는 샘플 프로젝트이다.

https://github.com/android/architecture-components-samples/tree/main/NavigationBasicSample

 

왜 Navigation 을 사용해야 하는가?

 Navigation 을 사용하면 무엇이 달라질까? 기존 방법으로 화면 전환을 구현하려면 Activity 를 stack 구조로 쌓아야만 했다. stack 구조를 사용하기 때문에 Activity 는 계속 메모리에 남게 된다. 반면 Navigation 을 사용하면 Fragment 를 갈아 끼우는 방식으로 화면 전환을 구현할 수 있다. Fragment 는 Activity 보다 가볍기 때문에 새 화면을 띄우는 데 걸리는 시간도 더 짧아진다.

 딥 링크 구현이 쉬워진다. 푸시 알림을 받고 해당 앱의 특정 페이지에 접근했다고 가정해 보자. 딥 링크 구현이 안 되어 있다면 뒤로 가기 버튼을 누르면 앱이 꺼진다. 하지만 딥 링크가 구현되었다면 마치 내가 앱을 켜고 해당 페이지까지 들어간 것과 같은 상황(백 스택)을 만들 수 있다.

 

Navigation 구성 요소

 Navigation 은 세 가지로 구성된다.

  • Navigation Graph
  • NavHost
  • NavController

 Navigation Graph 를 통해 화면간의 연결을 구성하고, 화면 구성을 시각적으로 확인할 수 있다. NavHost 는 Fragment 를 담아두는 껍데기 역할을 하고 한 프로젝트에서 여러 개의 NavHost 를 가질 수 있지만 NavHost 를 중첩된 구조로 가질 수는 없다.  NavController 는 NavHost 가 관리하는 객체이고 화면을 전환할 때 필요하다.

 

Navigation Graph

 Navigation Graph 는 res 패키지 안에 navigation 패키지를 만들고 nav_graph.xml 파일로 만들 수 있다. New -> Navigation Resourse File 을 통해 만들면 된다.

 xml 파일이기 때문에 layout.xml 과 비슷한 방법으로 코드를 작성하면 된다. navigation 태그에서 id 는 이후에 NavHost 로 지정해주기 위해 필요하다. startDestination 속성은 이 네비게이션에서 가장 기본이 되는 fragment 를 지정하면 된다. fragment 태그는 각각의 fragment 를 name 속성을 통해서 지정해 주면 된다. 중요한 건 id 속성과 name 속성이다. label 속성과 app:layout 속성은 화면들의 연결을 (개발자에게)시각적으로 보여주기 위한 역할을 하며, 기능에는 영향을 미치지 않는다. action 태그는 이 화면에 연결된 다른 화면을 지정할 수 있다. Design 탭에서 GUI 툴을 이용하여 연결하면 조금 더 편하게 코드를 작성할 수 있다. 여기서 사용된 id 는 화면을 전환하는 코드 NavController.navigate( <이부분> ) 에서 사용할 수 있다.

 참고로 navigation 태그는 중첩이 가능하다. 중첩에 대해 자세히 알고 싶다면 다음 두 링크를 참고하라. 탐색 원리, Navigation 중첩

 

NavHost

 NavHost 는 Fragment 혹은 Activity 의 layout 파일에서 FragmentContainerView 의 속성으로 지정할 수 있다. id, name, defaultNaveHost, navGraph 중 하나라도 빠지면 화면이 제대로 뜨지 않을 수 있으니 주의하자. 특히 id 와 name 은 실수하기 좋다. id 는 원하는 이름 아무거나 지정해 주면 된다. name 에는 반드시 androidx 에 정의된 것을 사용해야 한다. 그리고 navGraph 에 방금 우리가 만든 navigation 태그의 id 를 입력해 준다.

 

NavController

 18 라인만 확인하면 된다. findNavController 를 통해 NavController 를 얻고, navigate 메소드를 호출하여 화면을 전환할 수 있다. action 에서 id 를 사용하는 방법은 내가 생각하기에 가장 간단하다고 생각하여 작성한 방식이며 다른 방법으로 오버로딩 된 navigate 를 호출할 수도 있다. 관련 문서를 참조하라. navigation 을 이용하더라도 화면과 관련된 로직이므로 Activity 나 Fragment 가 있는 곳에서 호출해야 한다. ViewModel 에서는 findNavController 를 호출할 수 없다. ViewModel 에서 클릭 이벤트를 처리하고 싶다면 SingleLiveEvent 에 관해 찾아보면 된다.

마지막으로 다시 한 번 내가 만든 오픈소스 홍보

https://github.com/HamBP/android-template

 

GitHub - HamBP/android-template

Contribute to HamBP/android-template development by creating an account on GitHub.

github.com