ViewPager2(뷰페이저2)
뷰페이저는 스와이프(손가락으로 화면을 탭하여 오른쪽이나 왼쪽으로 미는) 이벤트로 화면을 전환할 때 사용합니다. 우리가 사용하는 앱에서 흔히 볼 수 있는 화면이므로 이를 구성하려면 알아둘 필요가 있습니다. 2019년에 제공된 뷰페이저2는 기존의 뷰페이저 라이브러리보다 많은 기능을 제공하고 있으므로 뷰페이저2로 사용할 것을 권장드립니다.
뷰페이저2를 이용하려면 먼저 모듈 수준 그래들 파일의 dependencies 항목에 다음처럼 선언해야 합니다.
// 뷰 페이저2 선언
implementation 'androidx.viewpager2:viewpager2:1.0.0'
그리고 레이아웃 XML 파일에 뷰페이저2를 추가합니다.
// activity_main.xml 파일에 뷰페이저2 라이브러리 추가
<androidx.viewpager2.widget.ViewPager2
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
뷰페이저2는 화면을 항목으로 봅니다. 각 항목이 순서대로 나열되어 있는데 단지 한 화면에 하나의 항목이 나온다는 개념입니다. 따라서 리사이클러뷰에서 살펴본 어댑터를 적용해야 합니다. 뷰페이저2에 사용할 수 있는 어댑터는 2가지인데, 리사이클러뷰에서 봤던 RecyclerView.Adapter를 그대로 이용하거나 FragmentStateAdapter를 사용할 수도 있습니다.
리사이클러뷰 어댑터를 이용한 뷰페이저2 구현
뷰페이저2를 리사이클러뷰 어댑터로 구현하는 경우는 화면 구성이 같을 때에 이용합니다. 이를 위해서는 XML 화면 구성을 뷰홀더에 적용하기 위해, 별도로 구성된 XML 파일이 있어야 합니다. 저는 item_main.xml이라는 파일을 생성하여 간단한 화면 구성으로 작성했습니다.
// item_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/item_text"
android:textSize="30sp"
android:layout_gravity="center_vertical"
android:textColor="@color/white"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
그런 다음 뷰홀더와 뷰어댑터 클래스를 작성합니다. 각각의 클래스는 RecyclerView에서 해당 인터페이스를 상속받습니다. 아래의 뷰어댑터는 화면 3개를 뷰페이저2로 제공하는 어댑터입니다.
// 뷰페이저2 구현 - 리사이클러뷰 어댑터 이용
// 뷰홀더
class MyPagerViewHolder(val binding: ItemMainBinding): RecyclerView.ViewHolder(binding.root)
// 뷰어댑터
class MyPagerAdapter(val datas: MutableList<String>): RecyclerView.Adapter<RecyclerView.ViewHolder>(){
override fun getItemCount(): Int = datas.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder =
MyPagerViewHolder(ItemMainBinding.inflate(LayoutInflater.from(parent.context), parent, false))
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val binding = (holder as MyPagerViewHolder).binding
binding.itemText.text = datas[position]
when(position % 3) {
0 -> binding.itemRoot.setBackgroundColor(Color.RED)
1 -> binding.itemRoot.setBackgroundColor(Color.BLUE)
2 -> binding.itemRoot.setBackgroundColor(Color.GREEN)
}
}
}
마지막으로 이 어댑터를 뷰페이저2에 적용합니다.
// MainActivity.kt
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val datas = mutableListOf<String>()
for(i in 1..3){
datas.add("item $i")
}
// 뷰페이저2 어댑터에 MyPagerAdapter 적용
binding.viewpager.adapter = MyPagerAdapter(datas)
}
}
▶ 실행 결과
프래그먼트 어댑터를 이용한 뷰페이저2 구현
RecyclerView.Adapter를 이용해 뷰페이저2를 구현할 수도 있지만 대부분 각 항목(화면)은 복잡하게 작성되며 각각의 화면마다 구성이 다릅니다. 따라서 각 항목의 내용은 보통 프래그먼트로 작성합니다. 항목을 프래그먼트로 작성했으면 FragmentStateAdapter로 뷰페이저2를 구현합니다.
// 뷰페이저2 구현 - 프래그먼트 어댑터 이용
class MyFragmentPagerAdapter(activity: FragmentActivity): FragmentStateAdapter(activity) {
val fragments = listOf<Fragment>(OneFragment(), TwoFragment(), ThreeFragment())
override fun getItemCount(): Int = fragments.size
override fun createFragment(position: Int): Fragment = fragments[position]
}
FragmentStateAdapter를 상속받아 어댑터를 작성하며 getItemCount()와 createFragment() 함수를 재정의한 것입니다. getItemCount() 함수는 항목(화면)의 개수를 구하고 createFragment() 함수는 항목을 구성하는 프래그먼트 객체를 얻습니다. 그리고 createFragment() 함수에서 반환하는 프래그먼트 객체가 각 항목에 출력됩니다. 이를 위해서는 각 화면마다의 프래그먼트를 미리 만들어둬야 합니다.
마지막으로 이 어댑터를 뷰페이저2에 적용합니다. activity_main.xml 파일의 내용은 동일합니다.
// MainActivity.kt
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
// 뷰페이저2 어댑터에 MyFragmentPagerAdapter 적용
binding.viewpager.adapter = MyFragmentPagerAdapter(this)
}
}
▶ 실행 결과
뷰페이저2에서는 화면 스와이프 방향도 설정할 수 있습니다. 기본으로 가로 방향이 적용되는데, 만약 세로 스와이프로 뷰페이저2를 구성하고 싶다면 orientation 속성값을 다음처럼 설정합니다.
// 뷰페이저2를 세로로 적용
binding.viewpager.orientation = ViewPager2.ORIENTATION_VERTICAL
'📱 Android' 카테고리의 다른 글
[Android] ImageView(이미지뷰)를 보여주는 3가지 방법 (Kotlin) (0) | 2022.02.19 |
---|---|
[Android] Notification 객체로 상태바에 알림 띄우기 (Kotlin) (0) | 2022.02.12 |
[Android] 에뮬레이터 무한 로딩 오류 (0) | 2022.02.10 |
[Android] Custom Dialog 띄우기 (Kotlin) (0) | 2022.02.10 |