Develop/Kotlin

[kotlin] 코틀린 Android Bottom Navigation View 생성

JunJangE 2021. 7. 28. 15:30

이전에는 액티비티 프로젝트에 있는 바텀 네비게이션 바를 사용했는데 코드 이해를 위해 새롭게 만들어 보려고 한다. 이미 있는 프로젝트로 사용하면 시간은 빠를 수 있지만 코드 이해는 더딘 거 같고 커스텀으로 만들면 더 많은 예시를 사용할 수 있을 것 같다는 생각에 시도해 보았다.

Gradle Scripts -> build.gradle에 들어가 다음 코드를 추가하고 sync now를 해준다.

dependencies {
    implementation 'com.google.android.material:material:1.3.0'
}

그리고 res에 안드로이드 리소스 디렉터리를 menu 타입으로 생성한다.

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

    <item
        android:id="@+id/navigation_home"
        android:icon="@drawable/selector_bottom_navi_home_icon"
        android:title="@string/title_home" />

    <item
        android:id="@+id/navigation_search"
        android:icon="@drawable/selector_bottom_navi_search_icon"
        android:title="@string/title_search" />

    <item
        android:id="@+id/navigation_shop"
        android:icon="@drawable/selector_bottom_navi_shop_icon"
        android:title="@string/title_shop" />

    <item
        android:id="@+id/navigation_tip"
        android:icon="@drawable/selector_bottom_navi_tip_icon"
        android:title="@string/title_tip" />

    <item
        android:id="@+id/navigation_user"
        android:icon="@drawable/selector_bottom_navi_user_icon"
        android:title="@string/title_user" />

</menu>

다음으로 navigation 타입으로 또 하나의 리소스 디렉터리를 만들고 다음과 같이 작성한다.

<?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/mobile_navigation"
    app:startDestination="@+id/navigation_home">

    <fragment
        android:id="@+id/navigation_home"
        android:name="com.junjange.touring.ui.home.HomeFragment"
        android:label="Touring"
        tools:layout="@layout/fragment_home" />

    <fragment
        android:id="@+id/navigation_search"
        android:name="com.junjange.touring.ui.search.SearchFragment"
        android:label="@string/title_search"
        tools:layout="@layout/fragment_serch" />

    <fragment
        android:id="@+id/navigation_shop"
        android:name="com.junjange.touring.ui.shop.ShopFragment"
        android:label="@string/title_shop"
        tools:layout="@layout/fragment_shop" />
    <fragment
        android:id="@+id/navigation_tip"
        android:name="com.junjange.touring.ui.tip.TipFragment"
        android:label="@string/title_tip"
        tools:layout="@layout/fragment_shop" />
    <fragment
        android:id="@+id/navigation_user"
        android:name="com.junjange.touring.ui.user.UserFragment"
        android:label="@string/title_user"
        tools:layout="@layout/fragment_shop" />
</navigation>

이제 어떠한 화면으로 바텀 네비게이션을 꾸밀 건지 activity_main.xml에 다음 코드를 작성한다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="?attr/actionBarSize">

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu"
        app:labelVisibilityMode="labeled"
        android:theme="@style/Theme.AppCompat.DayNight.DarkActionBar" />

    <fragment
        android:id="@+id/nav_host_fragment_activity_main"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="false"
        app:layout_constraintBottom_toTopOf="@id/nav_view"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/mobile_navigation"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

xml 코드를 작성했다면 본격적으로 MainActivity와 Fragment를 연결해보자.

주석을 잘 확인하고 코드의 흐름을 보면서 작성하면 좋을 것 같다.

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.amazonaws.mobile.client.AWSMobileClient
import com.amazonaws.mobile.client.Callback
import com.amazonaws.mobile.client.UserStateDetails
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.junjange.touring.ui.home.HomeFragment
import com.junjange.touring.ui.search.SearchFragment
import com.junjange.touring.ui.shop.ShopFragment
import com.junjange.touring.ui.tip.TipFragment
import com.junjange.touring.ui.user.AuthActivity
import com.junjange.touring.ui.user.UserFragment
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    private lateinit var homeFragment: HomeFragment
    private lateinit var searchFragment: SearchFragment
    private lateinit var shopFragment: ShopFragment
    private lateinit var tipFragment: TipFragment
    private lateinit var userFragment: UserFragment

    private val TAG = AuthActivity::class.java.simpleName

    // 메모리에 올라갔을 때
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // 레이아웃과 연결
        setContentView(R.layout.activity_main)

        // 바텀네비게이션 변수 실행
        nav_view.setOnNavigationItemSelectedListener(onBottomNavItemSelectedListener)

        // 처음 뜨는 fragment 설정
        homeFragment = HomeFragment().newInstance()
        supportFragmentManager.beginTransaction().add(R.id.nav_host_fragment_activity_main, homeFragment).commit()


    // 바텀 네비게이션 아이템 클릭 리스터 설정
    private val onBottomNavItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener{
            val ap = true
            when (it.itemId) {
                R.id.navigation_home -> {
                    homeFragment = HomeFragment().newInstance()
                    supportFragmentManager.beginTransaction().replace(R.id.nav_host_fragment_activity_main, homeFragment).commit()
                    Log.d("ttt","홈")
                }
                R.id.navigation_search -> {
                    searchFragment = SearchFragment().newInstance()
                    supportFragmentManager.beginTransaction().replace(R.id.nav_host_fragment_activity_main, searchFragment).commit()
                    Log.d("ttt","검색")

                }
                R.id.navigation_shop -> {
                    shopFragment = ShopFragment().newInstance()
                    supportFragmentManager.beginTransaction().replace(R.id.nav_host_fragment_activity_main, shopFragment).commit()
                    Log.d("ttt","샵")

                }
                R.id.navigation_tip -> {
                    tipFragment = TipFragment().newInstance()
                    supportFragmentManager.beginTransaction().replace(R.id.nav_host_fragment_activity_main, tipFragment).commit()
                    Log.d("ttt","팁")

                }
                R.id.navigation_user -> {
                    if(ap == true) {
                        userFragment = UserFragment().newInstance()
                        supportFragmentManager.beginTransaction().replace(R.id.nav_host_fragment_activity_main, userFragment).commit()
                        Log.d("ttt","유저")

                    }
                }
            }
            true
    }

}

여기서 자신이 원하는 fragment 수만큼 생성하고 이름을 설정하여 위 코드에 붙인다.

fragment 코드는 다 똑같다.

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.junjange.touring.R

class HomeFragment : Fragment() {

    fun newInstance() : HomeFragment{
        return HomeFragment()
    }


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        return inflater.inflate(R.layout.fragment_home, container, false)
    }

}

위 코드를 모두 작성했다면 다음 실행 화면과 같이 나오는 것을 확인할 수 있다.

<실행 화면>

확실히 기존에 있는 바텀 네비게이션 프로젝트를 사용하지 않고 코드를 직접 짜면 코드를 이해하는데 더 수월한 거 같고 다양한 예시를 해결할 수 있을 것 같다. 또한 나중에 유지보수에 있어서 좋을 것 같다는 생각을 했다.

참고

github

 

GitHub - junjange/Kotlin-Learning: 코틀린 학습

코틀린 학습. Contribute to junjange/Kotlin-Learning development by creating an account on GitHub.

github.com