[안드로이드 Navigation 1] - 개념 및 초기설정

이영준·2022년 10월 26일
0

네비게이션은 안드로이드 개발의 트렌트인 single activtiy - multiple fragment 형태를 위하여 nav_graph.xml을 통하여 화면 전환을 할 수 있게 해주는 라이브러리다.

  • NavHostFragment는 이 내비게이션 기능에서 사용하는 Host Fragment이다
  • 내비게이션 기능을 이용하면 시각적으로 스토리보드로 사용이 가능하다.

📌 구성 요소

  • Navigation Graph : XML 리소스, 앱 내 fragment들을 한눈에 확인할 수 있다
  • Navigation Controller : App Navigation을 관리해주는 Navigation Host의 객체. 컨텐츠 전환을 조종한다.
  • Navigation Host : Navigation Graph 에서 대상을 표시하는 빈 컨테이너.
    대상 구성요소에는 Fragment 대상을 표시하는 기본 Navigation Host 구현인 NavHostFragment가 포함된다.

즉 Navigation Graph에서 특정 경로 이동을 Controller에게 전달하고, 이 Navigation Controller가 Navigation Host에 적절한 대상을 표시한다.

📌초기 설정

공식 문서를 토대로 초기설정을 해준다
https://developer.android.com/jetpack/androidx/releases/navigation#declaring_dependencies

🔑의존성 주입

build.grade(Modlue: Name)파일에
의존성을 주입해주고

//navigation
    def nav_version = "2.5.3"
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

plugin에 safeargs를 추가해준다.

id 'androidx.navigation.safeargs.kotlin'

build.gradle(Project: Name)
파일 최상단에 buildscript를 아래와 같이 추가해준다.

buildscript {
    repositories {
        google()
    }
    dependencies {
        def nav_version = "2.5.2"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
    }
}

안드로이드는 시간에 따라 gradle 파일 설정도 매번 바뀌고 버전 업그레이드도 상시 있어서 현재 버전에 맞게 입력을 해줘야할 것 같다.

원래는 maven(), google() 라이브러리도 import가 되어있지 않으면 build.gradle(Project: Name)에 써줘야 한다고 많은 문서에서 나와있는데 settings.gradle 파일에 pluginManagement에 명시가 되어있는 듯 하다.


app->new->android resource file로 가 아래와 같이 nav_graph 리소스 파일을 생성한다.

그리고 사용할 activity에서 design 뷰로 NavHostFragment를 화면에 드래그 해주면

안스가 자동으로 nav_graph를 인식하여 제안해준다. ok를 눌러 가져온다.

그리고 constraint를 주기 위하여 디자인 모드에서 fragmentContainerView의 (Infer Constraints)를 누르고 constraints를 적용해준다.

        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/fragmentContainerView2"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginStart="1dp"
            android:layout_marginTop="1dp"
            android:layout_marginEnd="1dp"
            android:layout_marginBottom="1dp"
            app:defaultNavHost="true"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:navGraph="@navigation/nav_graph" />
    </androidx.constraintlayout.widget.ConstraintLayout>

📌nav_graph에 fragment 추가 및 데이터 바인딩

nav_graph의 가운데의 추가 버튼을 눌러 프래그먼트를 생성한다. 생성한 프래그먼트를 더블클릭하면 xml 파일로 이동하여 바로 편집할 수 있다.

xml을 위와같이 만들어 실행하면 main_xml에 놓은 fragment_xml 파일이 보여지게 된다.

데이터 바인딩을 위하여 xml 파일을 layout 태그로 묶어주는 것을 잊지 말자

🔑fragment를 추가했는데 layout이 보이지 않을 때

미리 만든 fragment 레이아웃을 넣을 때

이미 있는 fragment를 nav_graph에 넣을 때 레이아웃이 안보이는 문제가 종종 생긴다

xmlns:tools="http://schemas.android.com/tools"

nav_graph.xml 상단의 tools가 xmlns:tools="http://schemas.android.com/res-auto" 가 아닌
xmlns:tools="http://schemas.android.com/tools" 로 지정되어있는지 확인해주고

그 안에 fragment 태그들의 tools들이

tools:layout="@layout/fragment_home"

과 같이 레이아웃이 정의되어있는지 확인하고 없으면 넣어준다.

🔑fragment에 databinding

nav_graph에 프래그먼트를 추가하면서 Homefragment.kt 파일이 자동으로 생성된 것을 볼 수 있는데

액티비티와 마찬가지로 데이터바인딩을 해준다.

class HomeFragment : Fragment() {
private lateinit var binding : FragmentHomeBinding ...
override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        binding = DataBindingUtil.inflate(inflater,R.layout.fragment_home, container, false)
        return binding.root
    } ...

기존에 있는 onCreate함수를 지우고 onCreateView에 데이터를 바인딩 하였다.
액티비티는 binding.root를 return 할 필요가 없는데 반면 fragment는 binding.root를 반환해주어야 한다.

마찬가지 방법으로 nav_graph에서 fragment를 하나 더 추가해 편집 후 kt 파일을 수정하였다.

SecondFragment.kt

package com.example.navdemo

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import com.example.navdemo.databinding.FragmentSecondBinding


class SecondFragment : Fragment() {
    private lateinit var binding: FragmentSecondBinding
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        binding = DataBindingUtil.inflate(inflater,R.layout.fragment_second, container, false)
        return binding.root
    }

}
profile
컴퓨터와 교육 그사이 어딘가

0개의 댓글