[Android] ViewPager2 DiffUtil

June·2023년 11월 2일
0
post-thumbnail

ViewPager2 DiffUtil

https://velog.io/@june0103/Android-Viewpager%EC%99%80-Viewpager2
ViewPager2의 향상된 기능 중 다음과 같이 설명하였다

DiffUtil

  • ViewPager2는 RecyclerView를 기반으로 구축되어, DiffUtil 유틸리티 클래스를 활용할 수 있다
  • 데이터 세트의 변경을 효과적으로 관리하고 변경 사항을 시각적으로 나타내는데 사용

RecyclerView에서 DiffUtil을 사용한 경험이 있기에 ViewPager2에도 적용해보며 연습해보려한다
저번에는 Indicator를 사용해보았고 이번엔 TabLayout을 같이 활용해보자

ViewPager2 DiffUtil 사용해보기

1. build.gradle 설정

dependencies {
    implementation 'androidx.viewpager2:viewpager2:1.0.0'
}

2. Layout file ViewPager2 설정

  • TabLayout은 Android 앱에서 탭 기반의 사용자 인터페이스를 구축하는 데 사용되는 Android Design Support Library와 Material Design의 일부로 주로 ViewPager와 함께 사용된다.
  • 다양한 탭 간에 콘텐츠를 전환하고 탭을 스와이프 또는 탭 선택을 통해 선택할 수 있는 기능을 제공한다.
fragment_view_pager_diff_util.xml

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

        <com.google.android.material.tabs.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="text"/>
        <com.google.android.material.tabs.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="text"/>
        <com.google.android.material.tabs.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="text"/>

    </com.google.android.material.tabs.TabLayout>

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

3. 슬라이드 할 Item Layout 설정

  • 신호등의 빨강 - 노랑 - 초록 색을 배경색으로 보여주며 TextView에 의미를 적으려한다.
viewpager_item.xml

    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="text"
        android:textSize="30sp"
        android:layout_margin="100dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

4. Model 설정

data class TrafficLightModel(val name: String, val backgroundColor: Int)

5. adapter설정

TrafficLightModelDiffCallback Class

  • DiffUtil은 아이템 목록의 변경 사항을 효율적으로 감지하고 처리하는 데 사용
  • areItemsTheSame는 이전 아이템과 새로운 아이템이 동일한지 여부를 확인
  • areContentsTheSame는 아이템의 내용이 동일한지 여부를 확인
class ViewPager2Adapter : ListAdapter<TrafficLightModel, ViewPager2Adapter.PageViewHolder>(TrafficLightModelDiffCallback()) {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PageViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        val binding = ViewpagerItemBinding.inflate(inflater, parent, false)
        return PageViewHolder(binding)
    }

    override fun onBindViewHolder(holder: PageViewHolder, position: Int) {
        val item = getItem(position)
        holder.bind(item)
    }

    inner class PageViewHolder(private val binding: ViewpagerItemBinding) : RecyclerView.ViewHolder(binding.root) {
        fun bind(item: TrafficLightModel) {
            // 백그라운드 색상을 설정
            val backgroundColor = ContextCompat.getColor(binding.root.context, item.backgroundColor)
            binding.root.setBackgroundColor(backgroundColor)
            binding.name.text = item.name
        }
    }
}

class TrafficLightModelDiffCallback : DiffUtil.ItemCallback<TrafficLightModel>() {
    override fun areItemsTheSame(oldItem: TrafficLightModel, newItem: TrafficLightModel): Boolean {
        return oldItem == newItem
    }

    override fun areContentsTheSame(oldItem: TrafficLightModel, newItem: TrafficLightModel): Boolean {
        return oldItem == newItem
    }
}

6. ViewPager 연결

  • trafficList Traffic Light 모델의 정보를 포함하는 리스트로 ViewPager2어댑터에 연결
  • tabTitle TabLayout의 탭 제목을 나타내는 리스트로 TabItem의 수와 맞춰줘야한다. 만약 TabItem의 수보다 적을시 java.lang.ArrayIndexOutOfBoundsException: length=2; index=2 와 같이 Index오류가 발생하게 된다.
  • TabLayoutMediator TabLayout과 ViewPager2를 연결
class ViewPagerDiffUtilFragment : Fragment() {
    private lateinit var fragmentViewPagerDiffUtilBinding: FragmentViewPagerDiffUtilBinding
    private lateinit var adapter: ViewPager2Adapter

    private val trafficList = listOf(
        TrafficLightModel("정지",R.color.red),
        TrafficLightModel("주의",R.color.yellow),
        TrafficLightModel("통과",R.color.green),
    )
    private val tabTitle = listOf("Red", "Yellow", "Green",)
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        fragmentViewPagerDiffUtilBinding = FragmentViewPagerDiffUtilBinding.inflate(inflater)

        adapter = ViewPager2Adapter()

        fragmentViewPagerDiffUtilBinding.run {
            viewpager2.adapter = adapter
            adapter.submitList(trafficList)

            TabLayoutMediator(vp2Tablayout, viewpager2) { tab, position ->
                tab.text = tabTitle[position]
            }.attach()
        }
        return fragmentViewPagerDiffUtilBinding.root
    }
}

7. 결과

profile
끝까지 해보자

0개의 댓글