[안드로이드] ViewPager2

hee09·2021년 11월 1일
0

안드로이드

목록 보기
15/20
post-thumbnail
post-custom-banner

ViwePager2

ViewPager2는 항목을 나열하기 위한 뷰입니다.

하나의 화면을 항목 하나로 보며 나열하기 때문에 AdapterView(adapter를 사용하는 View)에 해당합니다. 즉 Adapter를 사용하여 View를 출력해야 합니다.


1. ViewPager와 ViewPager2의 차이점

이전에는 ViewPager를 많이 사용하였는데 현재는 ViewPager2가 나왔습니다.
ViewPager2는 ViewPager와 비교하여 많은 이점을 가지고 있습니다.

  1. 수직 방향 지원

ViewPager2는 사용자의 제어에 따라 수평 방향은 물론 수직 방향으로 화면이 전환됩니다.
이는 xml에서 android:orientation 속성을 사용하고 코드에서는 설정한다면 setOrientation()을 사용합니다.

<androidx.viewpager2.widget.ViewPager2
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:orientation="vertical" />
  1. Right-to-left 지원
    ViewPager2는 right-to-left 페이징을 지원합니다. RTL 페이징은 위치에 따라 자동으로 활성화되지만 xml에서 android:layoutDirection 속성을 사용하고 코드에서 설정한다면 setLayoutDirection()을 이용하여 수동으로 활성화할 수 있습니다.
<androidx.viewpager2.widget.ViewPager2
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layoutDirection="rtl" />
  1. 수정가능 한 fragment
    Viewpager2는 수정이 가능한 fragment collection의 페이징을 지원하며 collection이 변경될 때 UI를 업데이트하도록 notifyDatasetChanged를 호출합니다.

즉, 앱이 runtime중에 fragment collection을 동적으로 수정할 수 있고 ViewPager2는 수정된 것을 표시한다는 뜻입니다.

  1. DiffUtil
    ViewPager2는 RecyclerView를 기반으로 작성되었기에 DiffUtil 클래스(RecyclerView에서 성능을 개선해주기 위해 사용) 에 접근할 수 있습니다.

2. depedency 선언

project 수준이나 modlue 수준의 build.gradle 파일에 depedency를 추가합니다.

// 작성일 기준 최신버전
implementation 'androidx.viewpager2:viewpager2:1.0.0'

3. ViewPager2 만들기

XML layout안에 ViewPager2를 선언합니다.

<androidx.viewpager2.widget.ViewPager2
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

이제 Adapter를 이용해 page에 뷰를 연결시켜야 하는데, 이를 위해 FragmentStateAdapter를 사용합니다. 이 예제에서는 Fragment를 ViewPager2에 연결시켰습니다.

class MainActivity : AppCompatActivity() {

    lateinit var tabLayout: TabLayout
    lateinit var viewPager2: ViewPager2

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        viewPager2 = findViewById(R.id.view_pager2)
		
        // FragmentStateAdapter 생성 후 ViewPager2에 적용
        val viewPager2Adapter = ViewPager2Adapter(this)
        viewPager2.adapter = viewPager2Adapter


    }

    class ViewPager2Adapter(fa: FragmentActivity): FragmentStateAdapter(fa) {
        // Fragment의 개수
        override fun getItemCount(): Int = 3

        // ViewPager2를 통해 연결할 Fragment들을 제공하는 메서드
        override fun createFragment(position: Int): Fragment {
            return when(position) {
                0 -> OneFragment()
                1 -> TwoFragment()
                else -> ThreeFragment()
            }
        }
    }
}

3.1 FragmentStateAdapter

FragmentStateAdapter는 ViewPager에서 사용하던 FragmentStatePagerAdapter와 비슷합니다.

FragmentStateAdapter는 RecyclerView의 Adapter를 상속받아 작성되어 있습니다.

  • 생성자 : FragmentActiviy 또는 Fragment 또는 FragmentManager and LifeCycle을 매개변수로 받는데 위의 예에서는 FragmentActivity를 생성자의 매개변수로 주었습니다.
    그래서 Adapter를 선언하고 생성자로 this로 설정하였는데 그 이유는 AppCompatActivity는 아래의 사진과 같이 FragmentActivity를 상속받았기 때문입니다.

  • getItemCount() : ViewPager2에 연결할 Fragment의 개수를 넘겨줍니다.

  • createFragment() : 지정된 위치와 연관된 Fragment를 넘겨줍니다.


3.2 TabLayout과 함께 사용

ViewPager2는 TabLayout과 많이 사용하는데, ViewPager에서 사용하던 방법과는 조금 다릅니다.

우선 xml에 TabLayout과 ViewPager2를 선언합니다.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>

Activity 코드에서는 TabLayoutMediator를 이용하여 TabLayout과 ViewPager2를 연결시킵니다.
TabLayoutMediator는 TabLayout과 ViewPager2를 연결시키기 위해 사용하는 클래스입니다.

// TabLayoutMediator : TabLayout과 ViewPager2를 연결시키는 중재자 역할
// Tab의 선택이나 ViewPager2가 드래그되는 것을 동기화시켜 서로 연결되게 만듭니다.
// 생성자의 매개변수는 TabLayout과 ViewPager2 그리고 TabConfigurationStrategy입니다.
// TabConfigurationStrategy는 Tab의 텍스트와 스티일을 설정하는 인터페이스입니다.
TabLayoutMediator(tabLayout, viewPager2) { tab, position ->
    // 탭의 제목을 설정하는 구문
    tab.text = "Fragment ${position + 1}"
}.attach() // attach를 사용하여 TabLayout과 ViewPager를 연결

위에서 사용한 예제의 소스 코드는 깃허브 링크에 있습니다.


참조
ViewPager2 애니메이션 설정하기
안드로이드 developer - Migrate from ViewPager to ViewPager2
안드로이드 developer - crete ViewPager2
안드로이드 developer - slide between fragments using ViewPager2

틀린 부분은 댓글로 남겨주시면 수정하겠습니다..!!

profile
되새기기 위해 기록
post-custom-banner

0개의 댓글