본문 바로가기
Development/Android

[Android] Kotlin + BottomNavigationView + Fragment + ViewPager2 사용하기

by du.it.ddu 2020. 8. 6.
반응형

이전 포스팅에 이어 ViewPager2를 사용해 볼 것이다.

이전 포스팅의 코드를 수정 하며 진행 할 것이니 https://doitddo.tistory.com/88를 먼저 참고하는 것이 좋다.


- 종속성 추가

ViewPager2를 사용하기 위해서 종속성을 추가한다.

...

android {
    ...
}

dependencies {
    ...

    // ViewPager2
    implementation "androidx.viewpager2:viewpager2:1.0.0"
}

 버전이 높지는 않다.

https://developer.android.com/jetpack/androidx/releases/viewpager2?hl=ko를 참고하는 것을 권장한다.


- 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:background="#FFFFFF"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

        <androidx.viewpager2.widget.ViewPager2
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:id="@+id/vp_main"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toTopOf="@+id/bnv_main"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"/>

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:layout_width="0dp"
            android:layout_height="?attr/actionBarSize"
            android:id="@+id/bnv_main"
            android:background="#FFFFFF"
            app:menu="@menu/navi_menu"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

 이전 코드의 FrameLayout을 ViewPager2로 변경하기만 하면 끝이다.


- ViewPager2를 위한 어댑터 작성

class MainViewPagerAdapter(activity: AppCompatActivity, private val fragments: List<Fragment>) : FragmentStateAdapter(activity) {
    override fun getItemCount(): Int = fragments.size
    override fun createFragment(position: Int): Fragment = fragments[position]
}

위와 같이 작성하면 된다.

FragmentStateAdapter를 상속하고 파라미터로 Acitivty를 넘겨준다. 그리고 Fragment의 리스트를 넘겨주도록 한다.


- MainActivity 수정

class MainActivity : AppCompatActivity() {
    private val fragmentOne by lazy { FragmentOne() }
    private val fragmentTwo by lazy { FragmentTwo() }
    private val fragmentThree by lazy { FragmentThree() }

    private val fragments: List<Fragment> = listOf(
        fragmentOne, fragmentTwo, fragmentThree
    )

    private val pagerAdapter: MainViewPagerAdapter by lazy {
        MainViewPagerAdapter(this, fragments)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        initViewPager()
        initNavigationBar()
    }

    private fun initNavigationBar() {
        bnv_main.run {
            setOnNavigationItemSelectedListener {
                val page = when(it.itemId) {
                    R.id.first -> 0
                    R.id.second -> 1
                    R.id.third -> 2
                    else -> 0
                }

                if (page != vp_main.currentItem) {
                    vp_main.currentItem = page
                }

                true
            }
            selectedItemId = R.id.first
        }
    }

    private fun initViewPager() {
        vp_main.run {
            adapter = pagerAdapter
            registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
                override fun onPageSelected(position: Int) {
                    val navigation = when(position) {
                        0 -> R.id.first
                        1 -> R.id.second
                        2 -> R.id.third
                        else -> R.id.first
                    }

                    if (bnv_main.selectedItemId != navigation) {
                        bnv_main.selectedItemId = navigation
                    }
                }
            })
        }
    }
}

위와 같이 작성한다.

BottomNavigationView의 아이템 혹은 ViewPager의 아이템이 선택되었을 때 서로의 위치에 맞는 아이템을 선택해주도록 하기 위해 각각의 이벤트 리스너를 설정해준다.


- 실행

이제 끝났다. 굉장히 간단하지 않은가?

실행하면 아래와 같이 화면이 나올 것이다. BottomNavigationView의 아이템도 클릭 해 보고 좌우 스와이프를 이용해 화면을 변경 해 보자.


ViewPager2를 사용하면 좌우 스와이프로 화면을 이동시키는 것을 간단하게 지원할 수 있다.

참고로 ViewPager2를 RecyclerViewAdapter 또한 사용 가능하다.

이전 예제에 이어 Fragment를 활용하기 위해 위와 같은 방법을 사용하였으며, 이 외에도 방법은 여러가지가 있다.

RecyclerViewAdapter를 활용하는 것도 해 보기 바란다.

반응형