Android/오르다 다이어리

[Android/오르다 다이어리] 레거시 리팩토링 03 - Navigation Component 적용

yujinius 2025. 2. 20. 00:39
[Android/오르다 다이어리] 레거시 리팩토링 03 - Navigation Component 적용

이전 글: https://yujinius45.tistory.com/156

 

[Android/오르다 다이어리] 레거시 리팩토링 02 - targetSdk 34 적용 이슈와 해결

보호되어 있는 글입니다. 내용을 보시려면 비밀번호를 입력하세요.

yujinius45.tistory.com

 

✅ SDK 업그레이드 관련 간단 정보 (이전 글 요약)

지난 글에서 오르다 다이어리의 targetSdkVersion을 업그레이드하면서 권한 설정을 수정했다.

당시 필요한 변경 사항을 직접 찾아 적용했는데, 최근 Android Studio에서 제공하는 SDK Upgrade Assistant라는 기능이 있다는 것을 알게 되었다.

✅ SDK Upgrade Assistant란?

  • Android Studio의 도구 중 하나로, 버전 업그레이드 시 필요한 변경 사항을 자동으로 분석하고 가이드해준다.
  • targetSdkVersion을 변경하면 API 변경점, 권한 정책 변경, 비호환 요소 등을 체크할 수 있어, 업그레이드 시 놓치기 쉬운 부분을 쉽게 보완할 수 있다.
  • 결론: 다음 SDK 업그레이드 시에는 이 도구를 적극 활용하면 더 편리할 듯하다.

▼ 아래처럼 되어 있다.

 

📌 SDK 업그레이드는 이미 직접 적용한 상태이므로, 이번 작업에서는 기존 Activity 기반 네비게이션을 Fragment 기반으로 전환하는 과정에 집중한다


 

오르다 다이어리의 레거시 코드를 리팩토링하면서 가장 먼저 해결해야 할 문제로 화면 구성과 데이터 관리 방식 개선을 뽑았다.

오르다 다이어리의 기존 화면 구조는 모든 기능이 개별 Activity로 구성되어 있으며, 화면 간 이동은 Intent를 통해 이루어졌다.

이 방식은 화면 이동이 직관적이지 않고, Activity 간 전환 비용이 발생하며, UI 상태 관리가 어렵다는 단점이 있었다.

이 문제를 해결하기 위해 하나의 MainActivity에서 여러 개의 Fragment를 관리하는 구조로 변경하고, Navigation ComponentBottomNavigationView를 적용하여 Fragment 간 전환을 간편하게 만들고자 한다.


📌 기존 오르다 다이어리의 화면 구조와 문제점

🔍 기존 화면 구조

🚨 기존 구조의 문제점

화면 이동의 불편함

  • 현재 사용자는 메인 화면에서 버튼을 눌러 특정 화면으로 이동할 수 있지만, 다른 화면으로 이동하려면 항상 백 버튼을 눌러 MainActivity로 돌아와서 다시 다른 버튼을 눌러야 한다.
  • 즉, 일정 화면에서 일기 화면으로 바로 이동할 수 없고, 항상 MainActivity를 거쳐야 하는 구조다.

UI 상태 관리 부족

  • 일부 화면의 UI 상태가 유지되지 않는다.
  • Configuration Change(예: 화면 회전) 발생 시 앱이 종료되거나, 데이터가 초기화되는 문제가 있다.

Activity 개수가 많아 성능 저하 우려

  • 각 화면이 독립적인 Activity로 이루어져 있어, 화면 전환 시 메모리 사용량이 증가한다.
  • 사용자가 여러 화면을 빠르게 전환하면 불필요한 Activity가 누적되어 앱 성능에 영향을 미칠 수 있다.

비효율적인 사용자 경험(UI/UX)

  • 한 화면에서 다른 화면으로 바로 이동하는 기능이 부족하여, 사용자가 불편함을 느낀다.
  • 네비게이션 바와 같은 직관적인 전환 기능이 없어 앱 사용 경험이 비효율적이다.

🎥 관련 영상


💡 해결 방법: Single Activity + Multi Fragment 구조로 전환

기존 구조의 문제를 해결하기 위해, 하단 네비게이션 바(Bottom Navigation Bar)를 도입하여 사용자들이 더욱 직관적으로 화면을 전환할 수 있도록 개선하기로 했다.
이를 위해 각 Activity를 Fragment로 변경하고, Navigation Component를 활용하여 Fragment 전환을 관리하도록 구조를 변경하고자 한다.

📌 리팩토링 후 새로운 화면 구조

 

하단 네비게이션 바 추가 → 빠른 화면 전환 가능으로 사용자 경험 개선

Fragment 전환 방식 사용 → Activity 생성 부담 감소

ViewModel을 활용한 UI 상태 유지 가능 (추후 적용 예정)

 


💡 Navigation Component 적용 과정

1️⃣ nav_graph.xml 생성 및 Fragment 등록

Navigation Component를 사용하기 위해 nav_graph.xml을 생성하고, 기존 Activity를 Fragment로 등록했다.

📌 적용된 코드 (nav_graph.xml)

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    app:startDestination="@id/homeFragment">

    <fragment
        android:id="@+id/homeFragment"
        android:name="smu.team3_orda_diary.HomeFragment"
        android:label="Home" />

    <fragment
        android:id="@+id/todolistFragment"
        android:name="smu.team3_orda_diary.ToDoListFragment"
        android:label="Todolist" />

    <fragment
        android:id="@+id/mapMemoFragment"
        android:name="smu.team3_orda_diary.MapMemoFragment"
        android:label="Map Memo" />

    <fragment
        android:id="@+id/diaryListFragment"
        android:name="smu.team3_orda_diary.DiaryListFragment"
        android:label="Diary List" />

    <fragment
        android:id="@+id/alarmFragment"
        android:name="smu.team3_orda_diary.AlarmFragment"
        android:label="Alarm" />
</navigation>

 

BottomNavigationView와 연결하여 클릭 시 자동으로 Fragment 이동이 가능하게 만들었다.


2️⃣ BottomNavigationView 추가 및 Navigation 연동

  • 기존 Activity 간 이동 버튼을 제거하고, BottomNavigationView를 사용해 Fragment 전환을 자동화했다.
  • 메뉴 ID와 Fragment ID를 일치시키는 것이 중요하다. (초기에 ID 불일치 문제로 오류가 발생했다.)

🤣 Navigation Component 설정 실수로 발생한 오류 해결기

프로젝트에서 BottomNavigationViewNavigation Component를 연동하는 과정에서, bottom_nav_menu.xml의 메뉴 ID와 nav_graph.xml의 Fragment ID가 일치하지 않아 NavigationUI가 목적지를 찾지 못하는 오류가 발생했다.
오류 메시지를 분석한 결과, menu의 ID(nav_home, nav_schedule 등)와 nav_graph.xml에서 해당 Fragment의 ID(homeFragment, todolistFragment 등)가 불일치한 것이 원인이었다. 이를 해결하기 위해 모든 메뉴 ID를 Fragment ID와 동일하게 통일하였고, 이후 NavigationUI가 정상적으로 목적지를 찾으며 오류 없이 BottomNavigationView를 통한 Fragment 전환이 원활하게 이루어졌다. 오랜만에 xml으로 돌아오다 보니 이름 맞추는 것을 망각하고 있었다.

▲ 위의 캡쳐처럼 id를 동일하게 설정해야 하는 것! 잊지말자!!!!

 

 

📌 수정된 bottom_nav_menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/homeFragment"
        android:icon="@drawable/ic_home_24dp"
        android:title="홈" />

    <item
        android:id="@+id/todolistFragment"
        android:icon="@drawable/ic_today_24dp"
        android:title="일정관리" />

    <item
        android:id="@+id/mapMemoFragment"
        android:icon="@drawable/ic_location_on_24dp"
        android:title="지도 메모" />

    <item
        android:id="@+id/diaryListFragment"
        android:icon="@drawable/ic_feed_24dp"
        android:title="일기장" />

    <item
        android:id="@+id/alarmFragment"
        android:icon="@drawable/ic_alarm_24dp"
        android:title="알람" />
</menu>

 

Navigation ComponentBottomNavigationView를 연동하여 Fragment 전환을 자동화했다.


3️⃣ MainActivity 수정 (findNavController() 오류 해결)

초기에 findNavController(this, R.id.fragmentContainer) 호출 시 NavController가 설정되지 않아 IllegalStateException 오류가 발생했다.

이를 해결하기 위해 NavHostFragment에서 직접 NavController를 가져오는 방식으로 수정했다.

 

📌 수정된 MainActivity.java

NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager()
        .findFragmentById(R.id.fragmentContainer);
if (navHostFragment != null) {
    navController = navHostFragment.getNavController();
}
NavigationUI.setupWithNavController(binding.bottomNavigation, navController);

 

findNavController()를 안전하게 호출하도록 변경했다.

 


📌 현재 상태 & 다음 작업

Fragment 전환이 정상적으로 동작하는 것까지 확인했다. 🎉

🎥 관련 영상

 

✔ 현재는 빈 화면 전환만 되는 상태이며, 기존 Activity의 기능을 각각 Fragment로 이동하는 작업이 필요하다.

✔ 이후 각 Fragment에 기존 기능을 옮겨서 완전히 Fragment 기반으로 전환할 예정이다.

 


📌 마무리

이번 작업을 통해 BottomNavigationView + Navigation Component를 활용하여 Fragment 기반 네비게이션 구조를 적용했다.

 

기존 Activity 간 이동 방식에서 Fragment 전환 방식으로 변경하면서 nav_graph 등을 활용해 코드가 깔끔해졌다.

 

🔥 이후 작업에서는 기존 Activity의 UI와 기능을 Fragment로 이동하며, 필요에 따라 ViewModel을 활용한 데이터 관리도 적용할 계획이다.

 

📌 다음 목표: 기존 Activity의 UI 및 기능을 각각 Fragment로 마이그레이션하기!