Android

[Android] BottomNavigation + ViewPager2

YOONJELLY 2022. 4. 6. 13:38

 

 

BottomNavigation ( + ViewPager2)

 

종속성 추가

android {
    buildFeatures {
        viewBinding true
    }
}

dependencies {
		...
    implementation "androidx.viewpager2:viewpager2:1.0.0"
}

뷰바인딩을 사용하기 위해 뷰바인딩 속성도 추가해주었다!

 

아이템 추가

 

res → new → Android Resource File

 

Resource type을 Menu로 하고 Directory name도 menu로 해서 리소스 파일을 생성해준다

 

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/item_search"
        android:title="search"/>
    <item
        android:id="@+id/item_favorite"
        android:title="favorite"/>
</menu>

 

해당 파일에서 사용할 아이템들을 정의해준다.

 

메인 레이아웃

 

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"/>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:menu="@menu/menu_bottom"/>

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

뷰페이저 어댑터

 

class ViewPagerAdapter(fragment: FragmentActivity) : FragmentStateAdapter(fragment) {
    
		override fun getItemCount(): Int = FRAGMENTS.size

    override fun createFragment(position: Int): Fragment = FRAGMENTS[position]

    companion object {
        private val FRAGMENTS = listOf(
            SearchFragment(),
            FavoriteFragment()
        )
    }
}

companion object를 사용하여 적용될 fragment들을 list로 넣어 변수를 가져다 쓰도록 했다.

 

 

메인 액티비티

 

class MainActivity : AppCompatActivity() {

		// 전역 변수로 바인딩 객체 선언
    private var _binding: ActivityMainBinding? = null
		// 매번 null 체크를 할 필요 없이 편의성을 위해 바인딩 변수 재 선언
    private val binding get() = _binding!!

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

        _binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

				// 뷰페이저에 어댑터 연결
        binding.viewpager.adapter = ViewPagerAdapter(this)

				// 슬라이드하여 페이지가 변경되면 바텀네비게이션의 탭도 그 페이지로 활성화
        binding.viewpager.registerOnPageChangeCallback(
            object: ViewPager2.OnPageChangeCallback() {
                override fun onPageSelected(position: Int) {
                    super.onPageSelected(position)
                    binding.bottomNavigation.menu.getItem(position).isChecked = true
                }
            }
        )

        binding.bottomNavigation.run {
            setOnItemSelectedListener { item ->
                when(item.itemId) {
                    R.id.item_search -> {
                        binding.viewpager.currentItem = 0
                        true
                    }
                    R.id.item_favorite -> {
                        binding.viewpager.currentItem = 1
                        true
                    }
                    else -> false
                }
            }
        }
    }

		// 액티비티가 destroy될 때 binding class 인스턴스 참조 정리
    override fun onDestroy() {
        super.onDestroy()
        _binding = null
    }
}