[Android] ViewPager2 사용하기

3 분 소요

Intro

👩 이번 시간에는 ViewPager2이란 무엇이고, 기존에 존재했던 ViewPager하고는 무슨 차이가 존재하는지에 중점을 두어 알아볼 것이다.

그렇다면 우선 ViewPager란, ViewPager2란 무엇인지 정확히 이해하고 넘어가자!!


🙋‍♀️ ViewPager이란?

화면 슬라이드는 하나의 전체 화면에서 다른 화면으로 전환하는 것으로, 설정 마법사 또는 슬라이드쇼와 같은 UI에서 일반적으로 사용됩니다.
ViewPager 객체는 화면 슬라이드에 자동으로 애니메이션을 적용할 수 있습니다.


🙋 ViewPager vs ViewPager2

👩 그렇다면 ViewPager와 ViewPager2의 차이점은 무엇일까?

우선 ViewPager2가 무엇인지부터 살펴보자!

ViewPager2는 ViewPager 라이브러리의 개선된 버전으로, 향상된 기능을 제공하며 ViewPager 사용 시 발생하는 일반적인 문제를 해결합니다.

그렇다면 viewpager2로 이전했을 경우, 얻을 수 있는 이점은 무엇일까?

  • 기존 가로 페이징은 물론 세로 페이징도 지원한다.
    • andoird:orientation 속성을 설정하여 ViewPager2 요소의 세로 페이징을 사용 설정할 수 있습니다.
  • 오른쪽에서 왼쪽 페이징을 지원한다.

  • 수정 가능한 프래그먼트 컬렉션을 통해 페이징을 지원한다.
    • 기본 컬렉션이 변경되면 notifyDatasetChanged()를 호출해 UI를 업데이트한다.


🙋‍♀️ ViewPager2 사용법

👩 그렇다면 본격적으로 ViewPager2 사용법에 대해서 알아보자.


👩‍💻 AndroidX 종속 항목 추가

  • viewpager2를 사용하기 위해서는 프로젝트의 build.gradle 파일에 아래 코드를 통해서 AndroidX 종속 항목을 추가해야 한다.
    dependencies {
      implementation("androidx.viewpager2:viewpager2:1.0.0")
    }
    

그렇다면 viewpager2의 사용 준비는 마친 것이다.


👩‍💻 동일 요소로 구성 vs 서로 다른 프래그먼트로 구성

👩 viewpager2의 구현은 슬라이드를 진행할 요소에 따라서 두가지로 나뉜다.

  • 를 통해 페이징 - RecyclerView.Adapter 사용
  • 프래그먼트를 통해 페이징 - FragmentStateAdapter 사용
    • 정해진 소수의 프래그먼트를 통해 페이징할 경우 포함
    • 많은 수, 알 수 없는 수의 프래그먼트를 통해 페이징할 경우 포함

필자의 경우, 프래그먼트를 를 통해 페이징할 것이므로 FragmentStateAdapter를 사용해 viewpager2를 구현할 것이다!

🙋‍♀️ activity.xml

우선 viewpager2가 위치한 activity.xml을 구성할 것이다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <androidx.viewpager2.widget.ViewPager2
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        //세로 페이징 설정
        android:orientation="vertical"
        android:id="@+id/viewpager2"/>
</LinearLayout>

해당 코드는 간단하므로 추가 설명을 진행하지 않겠다.

🙋‍♀️ Fragment 구성

👩 지금부터는 여러 Fragment의 기본이 될 하나의 Fragment를 구성할 것이다.

  • 해당 Fragment를 수정하여 서로 다른 Fragment로 만든 후 슬라이드 시킬 것이다.

base_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center">

    <TextView
        android:textSize="50dp"
        android:textStyle="bold"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="First Fragment"/>

</LinearLayout>
  • 간단하게 하나의 textview로 화면을 구성했다.
  • 서로 다른 fragment는 배경색으로 구분된다.


BaseFragment.kt

class BaseFragment(order: Int) : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val idx = order
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.base_fragment, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
      // 슬라이드 순서에 따라 화면의 색과 text를 달리 하였다.
        if(idx == 1){
            view.setBackgroundColor(Color.parseColor("#9FC93C"))
            view.findViewById<TextView>(R.id.frag_text).setText("Frist Fragment")
        }else if(idx == 2){
            view.setBackgroundColor(Color.parseColor("#3DB7CC"))
            view.findViewById<TextView>(R.id.frag_text).setText("Second Fragment")
        }else{
            view.setBackgroundColor(Color.parseColor("#CC723D"))
            view.findViewById<TextView>(R.id.frag_text).setText("Third Fragment")
        }
    }
}

👩 프래그먼트 구현 시 생성하는 함수 세가지에 대해 간단히 알아보면 다음과 같다.

  • onCreate()
    • 프래그먼트를 생성할 때 시스템에서 호출하는 함수
    • 프래그먼트가 중단되고 다시 재개되었을 대, 유지하고자 하는 것을 초기화
      • ex) bundle data 가져오기 등..
  • onCreateView()
    • 프래그먼트가 UI를 처음으로 그릴 때 시스템에서 호출하는 함수
    • UI를 그린 후, View를 반환하게 된다.
    • 해당 프래그먼트가 UI를 제공하지 않을 경우, null을 반환한다.
  • onViewCreated()
    • onCreateView에서 return한 view를 가지고 있는다.
    • view의 다양한 요소들을 수정가능하다.

🙋‍♀️ViewPager2의 Adapter 구현

👩 필자의 경우, 위에서 설명했듯이 프래그먼트 페이징을 진행할 것이므로 FragmentStateAdapter를 통해서 ViewPager2의 Adpater를 구현할 것이다.

class ViewPager2Adapter(fragmentActivity: FragmentActivity): FragmentStateAdapter(fragmentActivity) {
    var fragList: ArrayList<Fragment> = ArrayList()
    // 어댑터에서 만들 페이지 수 반환(필수 구현)
    override fun getItemCount(): Int {
        return fragList.size
    }

    //ScreenSlidePageFragment의 인스턴스를 새 페이지로 제공하는 함수(필수 구현)
    override fun createFragment(position: Int): Fragment {
        return fragList[position]
    }

    // 새로운 Fragment를 리스트에 추가하는 함수
    fun addFragment(fragment: Fragment){
        fragList.add(fragment)
        notifyItemInserted(fragList.size-1)
    }
}

🙋‍♀️ ViewPager2Activity.kt

👩 이제 남은 과정은 위에서 구현한 ViewPager2Adapter를 viewpager2에 설정해주는 것이다.

class ViewPager2Activity : AppCompatActivity(){
    lateinit var binding: Viewpager2ActivityBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = Viewpager2ActivityBinding.inflate(layoutInflater)
        var root = binding.root
        setContentView(root)

        val viewPager2Adapter = ViewPager2Adapter(this)
        //세 개의 Fragment 추가
        viewPager2Adapter.addFragment(BaseFragment(1))
        viewPager2Adapter.addFragment(BaseFragment(2))
        viewPager2Adapter.addFragment(BaseFragment(3))
        //viewpager2에 adapter 설정
        binding.viewpager2.adapter = viewPager2Adapter
    }
}

🙋‍♀️ 결과

👩 여기까지 진행했다면 다음과 같은 결과를 확인할 수 있을 것이다.

그 과정을 정확히 이해하고 따라간다면 생각보다 구현이 그리 복잡하지 않다고 느낄 것이다!!:)

그렇다면 이번 게시글은 여기서 이만 마무리하겠다!!

끝~ ~(˘▾˘~)


✍ GIT REPO


📃참고

댓글남기기