막무가내 삽질 블로그

Android Jetpack Navigation 본문

Android

Android Jetpack Navigation

joong~ 2020. 3. 1. 02:41
728x90

안드로이드 개발자 문서, 코드랩, Developing을 참고했다.

 

AndroidX의 Navigation은 UI 전환을 쉽게 구현하는데 도움을 주는 라이브러리이다.

Navigation 에서는 이전 Destination(Fragment) 이 포함된 백스택을 자동으로 관리한다.

앱을 열때 첫 화면이 백스택에 배치되고 그 후 Navigate()를 실행 시켜 화면을 이동할 때 마다 백스택 맨위에 해당 Fragment가 놓여진다. (LIFO구조) 이전(뒤로가기) 기능 시, 스택의 맨위의 Fragment를 제거함으로 바로 이전의 Fragment가 호출된다.

 

 

전체 구조

 

res-navigation-navigation.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_root"
    app:startDestination="@+id/titleFragment">
    
    <fragment
        android:id="@+id/titleFragment"
        android:name="com.example.android.navigation.TitleFragment"
        android:label="@string/android_trivia"
        tools:layout="@layout/fragment_title">
        
        <action
            android:id="@+id/action_titleFragment_to_gameFragment"
            app:destination="@id/gameFragment"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right" />
    </fragment>
    
    <fragment
        android:id="@+id/gameFragment"
        android:name="com.example.android.navigation.GameFragment"
        android:label="@string/android_trivia"
        tools:layout="@layout/fragment_game">
        <action
            android:id="@+id/action_gameFragment_to_gameOverFragment"
            app:destination="@id/gameOverFragment"
            app:enterAnim="@anim/fade_in"
            app:exitAnim="@anim/fade_out"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right"
            app:popUpTo="@+id/gameFragment"
            app:popUpToInclusive="true" />
      
        <action
            android:id="@+id/action_gameFragment_to_gameWonFragment"
            app:destination="@id/gameWonFragment"
            app:enterAnim="@anim/slide_in_left"
            app:exitAnim="@anim/slide_out_right"
            app:popEnterAnim="@anim/slide_in_right"
            app:popExitAnim="@anim/slide_out_left"
            app:popUpTo="@+id/gameFragment"
            app:popUpToInclusive="true" />
    </fragment>
    
    <fragment
        android:id="@+id/gameWonFragment"
        android:name="com.example.android.navigation.GameWonFragment"
        android:label="@string/android_trivia"
        tools:layout="@layout/fragment_game_won">
        <argument
            android:name="numQuestions"
            app:argType="integer" />
        <argument
            android:name="numCorrect"
            app:argType="integer" />
        <action
            android:id="@+id/action_gameWonFragment_to_gameFragment"
            app:destination="@id/gameFragment"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right"
            app:popUpTo="@+id/titleFragment"/>
    </fragment>
    
    <fragment
        android:id="@+id/gameOverFragment"
        android:name="com.example.android.navigation.GameOverFragment"
        android:label="@string/android_trivia"
        tools:layout="@layout/fragment_game_over">
        <action
            android:id="@+id/action_gameOverFragment_to_gameFragment"
            app:destination="@id/gameFragment"
            app:enterAnim="@anim/slide_in_left"
            app:exitAnim="@anim/slide_out_right"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_right"
            app:popUpTo="@+id/titleFragment" />
    </fragment>
    
    <fragment
        android:id="@+id/rulesFragment"
        android:name="com.example.android.navigation.RulesFragment"
        android:label="@string/title_trivia_rules"
        tools:layout="@layout/fragment_rules" />
        
    <fragment
        android:id="@+id/aboutFragment"
        android:name="com.example.android.navigation.AboutFragment"
        android:label="@string/title_about_trivia"
        tools:layout="@layout/fragment_about" />
        
</navigation>

 

 

 

 

<?xml version="1.0" encoding="utf-8"?>
<layout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.drawerlayout.widget.DrawerLayout
        android:id="@+id/drawerLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <fragment
                android:id="@+id/myNavHostFragment"
                android:name="androidx.navigation.fragment.NavHostFragment"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:defaultNavHost="true"
                app:navGraph="@navigation/navigation" />
        </LinearLayout>

        <com.google.android.material.navigation.NavigationView
            android:id="@+id/navView"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:headerLayout="@layout/nav_header"
            app:menu="@menu/navdrawer_menu" />
    </androidx.drawerlayout.widget.DrawerLayout>
</layout>

 

MainActivity (NavHost)

class MainActivity : AppCompatActivity() {

    private lateinit var drawerLayout: DrawerLayout
    private lateinit var appBarConfiguration : AppBarConfiguration

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)

        drawerLayout = binding.drawerLayout

        val navController = this.findNavController(R.id.myNavHostFragment)
        NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)

        appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)

        navController.addOnDestinationChangedListener { nc: NavController, nd: NavDestination, bundle: Bundle? ->
            if (nd.id == nc.graph.startDestination) {
                drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
            } else {
                drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
            }
        }
        NavigationUI.setupWithNavController(binding.navView, navController)
    }

    override fun onSupportNavigateUp(): Boolean {
        val navController = this.findNavController(R.id.myNavHostFragment)
        return NavigationUI.navigateUp(navController, appBarConfiguration)
    }
}

 

 

 

 

 

참:https://developer.android.com/guide/navigation

Comments