[Android] Jetpack 알아보기 (3) - Navigation (bottomNavigation)

moKo·2021년 10월 12일
0

Android

목록 보기
6/13
post-thumbnail

개발하는 정대리님 유튜브를 통해 공부한 내용입니다.

🗺️ Navigation이란?

네비게이션, 흔히 코딩이 아니라도 일상생활에서 흔히 접하는 단어이다. 현실에서 사용되는 네비게이션과 비슷하게 안드로이드에서의 네비게이션은 사용자가 앱 내의 여러 콘텐츠를 탐색하고, 그곳에 들어갔다 나올 수 있게하는 상호작용을 의미한다. android jetpack에서의 navigation 구성요소는 단순한 버튼클릭에서부터 좀 더 복잡한 패턴에 이르기까지 여러가지를 구현하도록 도와준다.

구성요소 3가지

  • Navigation Graph : 모든 탐색 관련 정보가 하나의 중심 위치에 모여있는 xml 리소스이다. 여기엔 destination이라고 부르는 앱 내의 모든 개별적 콘텐츠 영역과 사용자가 앱에서 갈 수 있는 모든 이용 가능한 경로가 포함된다.
  • NavHost : navigation graph에서 대상을 표시하는 빈 컨테이너이다. 프래그먼트 대상을 표시하는 기본 NavHost 구현인 NavHostFragment가 포함된다.
  • NavController : NavHost에서 앱 탐색을 관리하는 객체로 사용자가 앱 내에서 이동할 때, NavHost에서 destination의 전환을 orchestrate한다.

Navigation gradle

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

classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"

Navigation과 bottomNavigation을 통해 간단한 예제 만들어보기

activity_main

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    android:weightSum="1"
    tools:context=".MainActivity">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/my_nav_host"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/my_bottom_nav"
        app:menu="@menu/bottom_nav_menu"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>
  • activity_main에서는 bottomNavigation의 뷰와 나중에 navigation을 통해 넘어갈 fragmentView들을 보여줄 fragmentcontainerView를 생성한다.

bottom_nav_menu

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

    <item
        android:id="@+id/homeFragment"
        android:title=""
        android:icon="@drawable/ic_home"
        />
    <item
        android:id="@+id/friendsFragment"
        android:title="친구"
        android:icon="@drawable/ic_friends"
        />
    <item
        android:id="@+id/musicFragment"
        android:title="음악"
        android:icon="@drawable/ic_music"
        />

</menu>
  • bottom_nav_menu에서는 bottomNavigation에 들어갈 메뉴들을 생성한다.
  • 이 이후 홈, 친구, 음악에 대한 각각 레이아웃을 만든다.

fragment_home

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/homeFragment"
    tools:context="com.project.bottom_navigation_tutorial.fragments.HomeFragment"
    android:background="#8BC34A">

    <TextView
        android:id="@+id/home_fragment_title"
        android:text="홈 프레그먼트"
        android:textSize="50dp"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</RelativeLayout>
  • 각 메뉴별로 보여질 레이아웃을 만든다. 다른 2개도 생성해줘야하나 글에선 생략한다.

HomeFragment.kt

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.project.bottom_navigation_tutorial.databinding.FragmentHomeBinding

class HomeFragment : Fragment() {

    private var mBinding: FragmentHomeBinding? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
		// 바인딩을 생성하여 뷰를 불러온다.
        val binding = FragmentHomeBinding.inflate(inflater, container, false)
        mBinding = binding
        return mBinding?.root

    }

    override fun onDestroyView() {
        mBinding = null
        super.onDestroyView()
    }
}
  • 메뉴별로 동작할 fragment의 클래스이다. viewBinding을 이용하여 각 뷰를 불러온다. 역시 다른 두 가지 메뉴도 동일하게 생성해주면 된다.
<?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/homeFragment">

    <fragment
        android:id="@+id/homeFragment"
        android:name="com.project.bottom_navigation_tutorial.fragments.HomeFragment"
        android:label="fragment_home"
        tools:layout="@layout/fragment_home" />
    <fragment
        android:id="@+id/friendsFragment"
        android:name="com.project.bottom_navigation_tutorial.fragments.FriendsFragment"
        android:label="fragment_friends"
        tools:layout="@layout/fragment_friends" />
    <fragment
        android:id="@+id/musicFragment"
        android:name="com.project.bottom_navigation_tutorial.fragments.MusicFragment"
        android:label="fragment_music"
        tools:layout="@layout/fragment_music" />
</navigation>
  • 위에서 설명했듯 navigation에 포함될 모든 뷰들을 모아놓고 순서를 정하고 홈을 정한다.

MainActivity.kt

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.NavigationUI
import com.project.bottom_navigation_tutorial.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var mBinding: ActivityMainBinding

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

        mBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(mBinding.root)

        // navigation host 가져오기
        val navHostFragment = supportFragmentManager.findFragmentById(R.id.my_nav_host) as NavHostFragment

        // navigation controller
        val navController = navHostFragment.navController

        // 바텀 네비게이션 뷰와 네비게이션을 묶어준다.
        NavigationUI.setupWithNavController(mBinding.myBottomNav, navController)
    }
}
  • bottomNavigation과 navigation의 뷰들을 바인딩하여 메뉴에 따라 알맞은 뷰를 보이게 한다.

결과화면

profile
🔥 Feelings fade, results remain

0개의 댓글