android
Android Navigation?
Seon Dev Notes
2024. 11. 26. 11:10
오늘은 안드로이드 개발에서 화면 전환을 효율적으로 관리하기 위한 Navigation에 대해 알아보겠다. Navigation은 앱 내에서 화면 간의 전환을 체계적으로 관리하며, 코드의 복잡도를 줄이고 UI 일관성을 유지하는 데 매우 유용하다.
Navigation이란?
사용자가 앱 내에서 여러 콘텐츠를 탐색하고, 원하는 화면으로 이동하거나 돌아올 수 있도록 하는 상호작용이다. Navigation은 특히 복잡한 앱 구조에서 화면 전환과 상태 관리를 체계적으로 처리할 수 있다.
Navigation의 주요 구성요소
Navigation은 여러 요소로 구성되어 있지만, 여기서는 핵심적인 3가지 구성 요소만 소개한다.
- NavGraph
- Navigation 관련 모든 정보를 담고 있는 구성 요소이다.
- 어떤 화면(목적지, Destination)이 있는지, 이동 시 어떤 액션을 취할 것인지, 전달할 데이터는 무엇인지 정의한다.
- Navigation Graph(XML 파일 형태)로 시각적으로 관리할 수 있다.
- NavHost
- Navigation Graph의 목적지 화면이 표시되는 빈 컨테이너 공간이다.
- 주로 FragmentContainerView를 사용하여 구현된다.
- NavController
- 화면 전환을 관리하는 객체이다.
- NavController는 NavHost에 목적지 화면을 표시하고, 이동이나 데이터 전달을 처리하다.
Navigation의 장점 및 기능
- 애니메이션 및 전환
- 화면 간 전환 시 표준화된 애니메이션을 제공한다.
- UI 패턴 지원
- 최소한의 추가 작업으로 탐색 창이나 하단 탐색과 같은 패턴을 구현할 수 있다.
- ViewModel과의 통합
- ViewModel의 범위를 Navigation Graph 단위로 지정하여 UI 관련 데이터를 화면 간에 쉽게 공유할 수 있다.
- 프래그먼트 트랜잭션 관리
- 프래그먼트 트랜잭션을 자동으로 처리하며, 개발자가 세부 구현에 신경 쓸 필요가 없다.
Navigation이 필요한 경우
아래와 같은 조건에서는 Navigation Component를 사용하는 것이 적합하다.
- 복잡한 화면 전환이 필요한 경우
- 여러 화면(프래그먼트 또는 액티비티)을 오가며 데이터나 상태를 전달해야 한다면 Navigation은 이를 효과적으로 관리할 수 있다.
- 백 스택 관리가 중요한 경우
- Navigation Component는 백 스택을 자동으로 관리하며, 사용자 정의 동작도 쉽게 구현할 수 있다.
- UI 일관성을 유지하고 싶은 경우
- Navigation Graph를 사용하면 앱의 화면 흐름을 시각적으로 설계하고 관리할 수 있어 협업 시에도 유리하다.
- Deep Link 및 Dynamic Feature Module을 지원하는 경우
- Deep Link를 쉽게 통합할 수 있으며, 동적 모듈 로딩에도 적합하다.
Navigation이 필요하지 않은 경우
반대로 아래와 같은 상황에서는 Navigation Component를 사용하지 않아도 괜찮다.
- 화면이 하나인 단순한 앱
- 계산기, 시계와 같은 단순 유틸리티 앱에서는 Navigation의 복잡도가 불필요하다.
- 커스텀 화면 전환이 필요한 경우
- 기본 전환 애니메이션 외의 고도화된 애니메이션은 제한이 있을 수 있다.
- 기존 방식으로 충분히 관리 가능한 경우
- 작은 앱에서는 Intent나 FragmentTransaction으로도 화면 전환과 백 스택 관리를 충분히 할 수 있다.
예제
- Navigation Graph(XML) 정의
<!-- res/navigation/nav_graph.xml -->
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
app:startDestination="@id/fragmentA">
<fragment
android:id="@+id/fragmentA"
android:name="com.example.app.FragmentA">
<action
android:id="@+id/action_to_fragmentB"
app:destination="@id/fragmentB" />
</fragment>
<fragment
android:id="@+id/fragmentB"
android:name="com.example.app.FragmentB" />
</navigation>
- NavHostFragment 설정
<!-- activity_main.xml --> <androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" android:layout_width="match_parent" android:layout_height="match_parent" app:navGraph="@navigation/nav_graph" app:defaultNavHost="true" />
- NavController로 화면 이동
class FragmentA : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val navController = findNavController() view.findViewById<Button>(R.id.button).setOnClickListener { navController.navigate(R.id.action_to_fragmentB) } } }