티스토리 뷰

반응형

Android 은 다양한 Widget 을 제공하고 있습니다. 그 중 대표적인 Widget을 뽑는다면 필자는 RecyclerView, ViewPager 뽑을 것입니다. Android Develop에서도 두 위젯을 좀 더 효율적으로 사용할 수 있도록 업데이트를 지속적으로 하고 있습니다.

이번 포스트는 RecyclerView 을 활용해서 ViewPager와 같은 기능을 만드는 방법에 대해서 공유 드리며, 더 나아가 ViewPager 의 개선버전인 ViewPager2 을 사용하는 방법에 대해서 공유 하겠습니다.

번외로 두 버전에 대한 Indicator 를 어떻게 만드는지를 공유하겠습니다.

 

 

RecyclerView 을 활용해서 ViewPager 기능 구현하기

RecyclerView 의 Cell에 ViewPager 을 구성할 경우 RecyclerView을 세로로 스크롤 할 때 버벅이는 이슈를 발견하게 될 것입니다. 앱에 따라서는 CPU 점유율이 높아지는 Case도 발생할 수 있습니다.

ViewPager의 단점을 개선하기 위해서 RecyclerView를 ViewPager 처럼 만들어서 사용한다면, RecyclerView의 자원 관리를 통해 버벅이는 이슈와 CPU 점유율을 줄 일 수 있을 것입니다.

 

Android Developer 에서는 PagerSnapHelper 을 제공하여 RecylcerView을 ViewPager와 같은 기능을 지원하고 있습니다.

RecyclerView를 활용해서 ViewPager를 구성하게 되면 ViewPager의 단점을 개선 되게 됩니다.

PagerSnapHelper을 사용하는 방법은 RecyclerView param 으로 넣어주기만 하면 사용 가능합니다. RecylclerView의 Apdater는 그대로 사용하면 됩니다.

package com.test.recyclerpagersnap

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.PagerSnapHelper
import androidx.recyclerview.widget.RecyclerView

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

        val listView = findViewById<RecyclerView>(R.id.list)
        listView.adapter= ImageAdapter()
        val pagerSnapHelper = PagerSnapHelper()
        pagerSnapHelper.attachToRecyclerView(listView)
    }
}

 

 

ViewPager2 을 활용한 기본 환경 설정하기

ViewPager의 개선 버전으로 ViewPager2를 제공하고 있습니다. ViewPager2 는 RecyclerView 로 구성되어서 ViewPager2의 Adpater 구성은 RecyclerView 와 동일합니다.

사진 넘기는 기능을 구현한다고 가정해보겠습니다. Adpater 구성은 아래와 같이 RecylcerView.Adapter 를 상속 받아서 처리합니다. Adapter 구성은 drawable에 있는 test_image_xxx.png 을 가져와 RecylcerView에 표시하는 기능을 구현하였습니다.

// ...
class ImageAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        val imgView = ImageView(parent.context).apply {
            this.layoutParams = ViewGroup.LayoutParams(getDisplayWidth(context), getRealDisplayHeight(context))
            this.scaleType = ImageView.ScaleType.CENTER_CROP
            this.setImageResource(R.drawable.test_image_001)
        }
        return object : RecyclerView.ViewHolder(imgView) {}
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val context = holder.itemView.context
        val index = if(position > 2) position - 3 else position
        val imageNm = "test_image_" + String.format(Locale.KOREA, "%03d", index +1)
        val identifier = context.resources.getIdentifier(imageNm, "drawable", context.packageName)
        (holder.itemView as? ImageView)?.setImageResource(identifier)
    }

    override fun getItemCount(): Int {
        return 3
    }

// ...
}

 

Adapter를 구성하였으면 ViewPager2에 연결 합니다. 아래 소스코드와 같이 ViewPager2에 만들어둔 Adapter을 연결하면됩니다.

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

        val viewPager2 = findViewById<ViewPager2>(R.id.list)
        viewPager2.adapter= ImageAdapter()
    }
}

 

java.lang.IllegalStateException: Pages must fill the whole ViewPager2 (use match_parent)

ViewPager2을 구성하다보면 위와 같은 Exception을 경험할 수 있습니다. ViewPager2 의 width 값을 wrap_content로 하였을 경우 발생하는 이슈로 width의 값을 match_parent 로 설정합니다.

 

번외) RecylcerView PagerSnapHelper 및 ViewPager2 Indicator 구성하기

RecylcerView PagerSnapHelper 및 ViewPage2 의 Indicator 는 Decoration 으로 구성합니다.

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

        // ...
        list.addItemDecoration(LinePagerIndicatorDecoration())
				// or
        viewpager2.addItemDecoration(LinePagerIndicatorDecoration())
    }
}

 

LinePagerIndicatorDecoration() 에 대한 소스는 LinePagerIndicator 에서 확인 가능하십니다.

 

 

마무리

Slider Page 구성하는 방법에 대해서 알아봤습니다. Slider를 사용하기 위해서 ViewPager2를 사용하는 것이 적당할 거 같지만, ViewPager2 안에 RecyclerView 를 제어하는 것에는 어려움이 있어서, 프로젝트 특성에 맞게 구성하는 것이 좋을거 같습니다.

 

 

참고

LinePagerIndeicator 참고한 소스

ViewPager2 - Android Developer

 

반응형
댓글