Android androidx: 뷰페이저2

timothy jeong·2021년 11월 9일
0

Android with Kotlin

목록 보기
27/69

뷰 페이저

뷰 페이저는 스와이프 이벤트로 화면을 전환할 때 사용한다. 플레이 스토어 앱을 보면 사용자가 손가락을 이용해 화면을 양옆으로 밀어 이전이나 다음 화면을 볼 수 있다. 이러한 기능이 뷰 페이저이다.

뷰 페이저는 플랫폼 API에서 제공하지 않기 때문에 androidx 라이브러리를 이용해 개발해야한다. 이러한 뷰 페이저는 2019년 뷰 페이저 2가 릴리즈 되었고, 더 유용한 기능을 많이 제공하기 때문에 이를 많이 쓴다.

뷰 페이저 사용

뷰 페이저를 쓰기 위해 의존성을 추가하자

implementation 'androidx.viewpager2:viewpager2:1.0.0'

그리고 메인 레이아웃에 뷰 페이저를 담을 공간 android:id="@+id/viewpager" 과 뷰 페이저에 표시될 항목을 담을 레이아웃 android:id="@+id/itemPagerTextView"을 작성하자. 이런 패턴은 리사이클러 뷰에서 썼던 방식과 동일하다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

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

    <Button
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="5"
        android:text="BUTTON"
        android:textSize="50sp"
        />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

        <TextView
            android:id="@+id/itemPagerTextView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:textColor="@color/white"
            tools:text="hello"
            android:textSize="40sp" />

</LinearLayout>

뷰 페이저2는 화면을 항목으로 본다. 각 항목이 순서대로 나열되어 있는데 단지 한 화면에 항목이 하나가 나온다는 개념이다. 따라서 리사이클러 뷰에서 살펴봤던 어댑터를 적용해야한다. 뷰 페이저2에 사용할 수 있는 어댑터는 2가지인데 리사이클러 뷰에서 봤던 RecyclerView.Adapter 를 그대로 이용하거나 FragmentStateAdapter 를 사용할 수 있다.

리사이클러 뷰 어댑터 이용

리사이클러 뷰 어댑터를 이용하는 것은 이전 포스팅에서 사용하던 방법과 큰 차이가 없다. 단지 뷰 페이저2의 어댑터로 적용만 하면 된다. 즉, 당연히 뷰 홀더도 만들어 줘야 한다.

class MyPagerViewHolder(val binding: ItemPagerBinding) : 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(
        ItemPagerBinding.inflate(LayoutInflater.from(parent.context), parent, false))

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val binding = (holder as MyPagerViewHolder).binding

        binding.itemPagerTextView.text = datas[position]
        when (position % 3) {
            0 -> binding.itemPagerTextView.setBackgroundColor(Color.RED)
            1 -> binding.itemPagerTextView.setBackgroundColor(Color.BLUE)
            2 -> binding.itemPagerTextView.setBackgroundColor(Color.GREEN)
        }
    }
}

그리고 mainActivity 코드를 다음과 같이 작성하면 된다.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        val datas = mutableListOf<String>()
        for (i in 1..10) {
            datas.add("item $i")
        }
        binding.viewpager.adapter = MyPagerAdapter(datas)
    }
}

콘텐츠 영역의 윗 영역을 위로 스와이프하면 다음 화면이 나타나고, 밑의 button 은 그대로 유지된다.

프레그먼트 어댑터 이용

위와 같이 리사이클러 뷰 어댑터를 이용해서 뷰 페이저2를 구현한 수도 있지만 대부분 각 항목(화면)은 복잡하게 작성된다. 따라서 각 항목의 내용은 프래그먼트로(따라서 액티비티와 같이) 작성한다.

만약 항목을 프레그먼트로 작성했으면 FragmentStateAdapter 로 뷰 페이저2를 구현한다. 각각의 프래그먼트 레이아웃과 클래스가 이미 준비되어있다고 보고 아래의 코드를 보자.

class MyFragmentPagerAdapter(activity: FragmentActivity) : FragmentStateAdapter(activity) {
    val fragments : List<Fragment>
    init {
        fragments = listOf(OneFragment(), TwoFragment(), ThreeFragment())
    }

    override fun getItemCount() = fragments.size

    override fun createFragment(position: Int): Fragment = fragments[position]
}
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.viewpager.adapter = MyFragmentPagerAdapter(this)
        //binding.viewpager.orientation = ViewPager2.ORIENTATION_VERTICAL 스와이프 방향 변경
    }
}

해당 액티비티에서는 스와이프할 때마다 다른 프레그먼트들이 나타난다.

profile
개발자

0개의 댓글