
https://velog.io/@june0103/Android-Viewpager%EC%99%80-Viewpager2
ViewPager2의 향상된 기능 중 다음과 같이 설명하였다
RecyclerView에서 DiffUtil을 사용한 경험이 있기에 ViewPager2에도 적용해보며 연습해보려한다
저번에는 Indicator를 사용해보았고 이번엔 TabLayout을 같이 활용해보자
dependencies {
implementation 'androidx.viewpager2:viewpager2:1.0.0'
}
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"/>
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" />
data class TrafficLightModel(val name: String, val backgroundColor: Int)
TrafficLightModelDiffCallback Class
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
}
}
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
}
}
