룬아님의 취중코딩

Android Navigation component 사용해보기 본문

개발/안드로이드 개발

Android Navigation component 사용해보기

룬아님 2019. 11. 8. 18:06

https://youtu.be/Y0Cs2MQxyIs

 

#안드로이드 스튜디오에서 Navigation을 활용하기 위해서는 안드로이드 스튜디오 버전이 3.3혹은 그 이상이여야 합니다.

 

1.  build.gradle 추가

dependencies {
  def nav_version = "2.1.0-rc01"

  // Java
  implementation "androidx.navigation:navigation-fragment:$nav_version"
  implementation "androidx.navigation:navigation-ui:$nav_version"

  // Kotlin
  implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
  implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

}

 

2. navigation graph 파일 만들기

navigation component를 시작하기 위해서는 경로를 나타내기 위한 xml파일이 필요합니다.

1. res디렉토리를 오른쪽 클릭하여 설정을 열고 New > Android Resource File

 

 

2. 이름을 nav_graph로 정하고 type을 Navigation으로 선택하여 생성합니다.

 

3. 그래프에 로직 만들기

제가 네비게이션을 이용하여 우선 구현할 로직은

메인 화면에서 버튼 클릭 -> 검색 화면으로 이동

메인 화면, 검색 화면에서 리스트 아이템 클릭 -> 상세 화면으로 이동

이 로직을 가지고 nav_graph를 채워주면 이런 구조가 됩니다.
main_screen에서만 search_screen으로 이동할 수 있고 detail_screen은 어느 화면에서도 이동할 수 있습니다.

이 Design화면에서는 기존 layout에서 사용했던 것처럼 드래그와 클릭등을 사용하여 간편하게 구현할 수도 있습니다.
costraintlayout에서 chain을 연결하듯 스크린의 가장자리에 생기는 원을 드래그하여 다른 스크린에 가져다 대면 위의 그림 처럼 화살표가 생기며 이동 경로가 정해집니다.

위의 그래프의 xml 코드입니다.

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@+id/main_screen">
    <!-- startDestination은 시작 fragment를 뜻합니다.
    	매니페스트에서 정하는 launch activity와는 다른 의미입니다. !-->
    <fragment
        android:id="@+id/main_screen"
        android:name="com.runeanim.mytoyproject.ui.main.MainFragment"
        android:label="Main screen">
        <action
            android:id="@+id/action_main_screen_to_search_screen"
            app:destination="@id/search_screen" />
        <!-- 이 action은 이동경로를 나타내는 것으로 보면 쉽습니다.
        	destination은 어떤 fragment로 이동하는지 정하는 것이기 때문에
            destination을 선언해주지 않으면 빌드가 되지 않습니다. !-->
    </fragment>

    <fragment
        android:id="@+id/search_screen"
        android:name="com.runeanim.mytoyproject.ui.search.SearchFragment"
        android:label="Search screen"
        tools:layout="@layout/search_fragment">
    </fragment>

    <fragment
        android:id="@+id/detail_screen"
        android:name="com.runeanim.mytoyproject.ui.detail.DetailFragment"
        android:label="Detail screen"
        tools:layout="@layout/detail_fragment"/>

    <action
        android:id="@+id/action_global_detail_screen"
        app:destination="@id/detail_screen" />
    <!-- fragment 테그 안에 있지 않은 action은 global action입니다.
    	특정 fragment에서만 이동가능한 뷰가 아니라 모든 뷰에서 접근 가능한 뷰일 때 사용합니다. !-->
</navigation>

 

4. Main 엑티비티 xml에 NavHostFragment 선언하기

 

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        .../>

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"

        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        .../>

</android.support.constraint.ConstraintLayout>

여기서 주목하셔야 할 것은 name, defaultNavHost와 navGraph 입니다.

android : name 속성은 NavHost 구현의 클래스 이름을 포함합니다.

app : navGraph 속성은 NavHostFragment를 탐색 그래프와 연결합니다.
탐색 그래프는이 NavHostFragment에서 사용자가 탐색 할 수있는 모든 대상을 지정합니다.

app : defaultNavHost = "true"속성은 NavHostFragment가 시스템 뒤로 버튼을 가로 채도록합니다. 하나의 NavHost 만 기본값이 될 수 있습니다. 동일한 레이아웃에 호스트가 여러 개인 경우 (예 : 2 개 패널 레이아웃) 기본 NavHost를 하나만 지정하십시오.

 

5. (선택) 툴바에 뒤로가기 추가하기

class MainActivity : AppCompatActivity() {

    private lateinit var appBarConfiguration: AppBarConfiguration
    private lateinit var navController: NavController

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)

        navController = Navigation.findNavController(this, R.id.nav_host_fragment)
        appBarConfiguration = AppBarConfiguration(navController.graph)
        setupActionBarWithNavController(navController, appBarConfiguration)
    }

    override fun onSupportNavigateUp(): Boolean {
        return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
    }
}

onCreate에 있는 코드로 툴바에 뒤로가기를 표시하고 onSupportNavagateUp을 override하여 뒤로 가기를 터치하면 뒤로 가지도록 구현할 수 있습니다.

 

6. 다른 screen으로 이동하기

viewTransactionsButton.setOnClickListener { view ->
   view.findNavController().navigate(R.id.action_main_screen_to_search_screen)
}

기본 사용법입니다.

fun moveScreenToSearchFragment() {
    Navigation.findNavController(viewDataBinding.root)
        .navigate(R.id.action_main_screen_to_search_screen)
}

아까 위의 graph에서 선언했던 main 스크린에서 search 스크린으로 이동하는 action을 사용하여 함수를 만들었습니다.

 

7. screen간 데이터 이동

private fun moveToDetailScreen(repositoryEntity: RepositoryEntity) {
    val bundle = with(repositoryEntity) {
        bundleOf(
            Constants.EXTRA_USER_NAME to ownerName,
            Constants.EXTRA_REPOSITORY_URL to fullName
        )
    }
    Navigation.findNavController(viewDataBinding.root)
        .navigate(R.id.action_global_detail_screen, bundle)
}

navigation에는 데이터를 이동하는 방법이 여러가지가 있습니다. 이 방법은 가장 간단하게 데이터를 넘기는 방법입니다.
번들을 만들고 navigate에 같이 넣어서 보내주면 됩니다.

arguments?.run {
    getUserAndRepositoryInfo(
        getString(Constants.EXTRA_REPOSITORY_URL) ?: "",
        getString(Constants.EXTRA_USER_NAME) ?: ""
    )
}

받는 쪽에서는 이런식으로 받아주면 됩니다.

다음 글에서는 안전하게 데이터 옮기는 법을 적겠습니다.

2019/11/11 - [개발/안드로이드 개발] - Android Navigation component 안전하게 데이터 넘기기

 

 

Navigation Componenet 적용 예제

 

myung6024/study-android-architecture

안드로이드 아키텍처 스터디. Contribute to myung6024/study-android-architecture development by creating an account on GitHub.

github.com

 

안드로이드 Navigation Component 공식 문서

 

Get started with the Navigation component  |  Android Developers

This topic shows you how to set up and work with the Navigation component. For a high level overview of the Navigation component, see the Navigation overview. Set up your environment Note: If you want to use Navigation with Android Studio, you must use And

developer.android.com

 

반응형
Comments