Android

[Android] ViewPager2 사용법

JunsuKim 2022. 8. 23.
728x90

ViewPager란?

 

애플리케이션을 사용하다보면 위와 같이 페이지를 양옆으로 넘길 수 있는 스와이프 기능을 종종 볼 수 있다.

이를 ViewPager(뷰 페이저)라고 한다.

 

원래 ViewPager가 있었지만 단점이 있어, 이를 보완하기 위해 ViewPager2가 등장하였다.

ViewPager2는 RecyclerView 기반으로 만들어진 컴포넌트이고, 사용법도 RecyclerView와 유사하다.

RecyclerView와의 차이점은 RecyclerView는 페이지를 어느 정도 넘기면 그 위치에서 정지하지만, ViewPager2는 일정 이상 페이지를 넘기면 자동으로 페이지가 넘어가진다.

1: 세로로 내려가는 RecyclerView, 2: 가로로 넘기는 ViewPager2

위를 보면 RecyclerView는 스크롤을 멈치면 그 자리에서 멈치지만, ViewPager2는 일정 페이지를 넘긴 후 손을 놓으면 자동으로 넘어가는 것을 확인할 수 있다.

 

이제 ViewPager2를 사용하는 방법을 알아보자.

사용 방법

 위에서 ViewPager2는 RecyclerView를 기반으로 만들어졌다고 하였다.

즉 RecyclerView Adapter를 적용해서 ViewPager를 구현할 수 있다.

RecyclerView Adapter 뿐만 아니라 Fragment Adapter를 이용할 수도 있다. 각 항목을 Fragment로 작성했다면 FragmentStateAdapter로 ViewPager를 구현할 수 있다.

각각의 사용법을 알아보자.

MainActivity

package com.example.myapplication

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.viewpager2.widget.ViewPager2

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

        val viewPager: ViewPager2 = findViewById(R.id.view_pager)
        val viewPagerAdapter = FragmentAdapter(this)

        viewPagerAdapter.addColor()

        viewPager.adapter = viewPagerAdapter
        viewPager.orientation = ViewPager2.ORIENTATION_HORIZONTAL
    }
}

viewPagerAdapter에 FragmentAdapter 또는 RecyclerViewAdapter를 적용시킨다.

각 Adapter들을 살펴보자.

RecyclerView Adapter

package com.example.myapplication

import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.graphics.drawable.toDrawable
import androidx.recyclerview.widget.RecyclerView

class RecyclerViewAdapter: RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() {
    private val color = mutableListOf<Int>()

    class ViewHolder(view: View): RecyclerView.ViewHolder(view) {
        val colorLayout: View = view.findViewById(R.id.color_layout)
    }
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder
    = ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.activity_color, parent, false))

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        with(holder) {
            colorLayout.background = color[position].toDrawable()
        }
    }

    override fun getItemCount(): Int = color.size

    fun addColor() {
        color.add(Color.parseColor("#FF0000"))
        color.add(Color.parseColor("#FFA500"))
        color.add(Color.parseColor("#FFFF00"))
        color.add(Color.parseColor("#008000"))
        color.add(Color.parseColor("#0000FF"))
        color.add(Color.parseColor("#4B0082"))
        color.add(Color.parseColor("#800080"))
        notifyDataSetChanged()
    }
}

RecyclerView Adapter를 할 때와 같다는 것을 확인할 수 있다.

FragmentAdapter

package com.example.myapplication

import android.graphics.Color
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter

class FragmentAdapter(fragment: FragmentActivity): FragmentStateAdapter(fragment) {
    private val color = mutableListOf<Int>()

    override fun getItemCount(): Int = color.size

    override fun createFragment(position: Int): Fragment {
        val colorFragment = ColorFragment()
        val bundle = Bundle()

        bundle.putInt("color", color[position])
        colorFragment.arguments = bundle

        return colorFragment
    }

    fun addColor() {
        color.add(Color.parseColor("#FF0000"))
        color.add(Color.parseColor("#FFA500"))
        color.add(Color.parseColor("#FFFF00"))
        color.add(Color.parseColor("#008000"))
        color.add(Color.parseColor("#0000FF"))
        color.add(Color.parseColor("#4B0082"))
        color.add(Color.parseColor("#800080"))
        notifyDataSetChanged()
    }
}

FragmentAdapter를 사용하기 위해선 당연히 Fragment가 있어야 한다.

Adapter에서 Bundle을 통해 색 데이터를 전달해줬으니, Fragment에서 이를 받아 출력을 해주면 된다.

ColorFragment

package com.example.myapplication

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

class ColorFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val rootView = inflater.inflate(R.layout.fragment_color, container, false)
        val colorView: View = rootView.findViewById(R.id.color_view)
        val color = requireArguments().getInt("color")
        colorView.setBackgroundColor(color)

        return rootView
    }
}

Bundle을 통해 Fragment와 Adapter간 데이터 전달을 시켜준다.

결과

728x90

댓글