class ViewPager2Activity : AppCompatActivity() {
private val binding by lazy { ActivityViewPager2Binding.inflate(layoutInflater) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
val list = listOf(
PageType.MAIN,
PageType.FAVORITE,
PageType.SETTING,
)
val list2 = listOf(
PageType.MAIN,
PageType.SETTING,
)
val adapter = PagerAdapter(list, this)
binding.pager.adapter = adapter
TabLayoutMediator(binding.tabLayout, binding.pager) { tab, position ->
tab.text = list[position].toString()
}.attach()
binding.checkbox.setOnCheckedChangeListener { _, isChecked ->
adapter.updateList(if (isChecked) list else list2)
}
}
}
enum class PageType {
MAIN,
FAVORITE,
SETTING
}
private class PagerAdapter(
initial: List<PageType>,
fragmentActivity: FragmentActivity
) : FragmentStateAdapter(fragmentActivity) {
private val list = mutableListOf<PageType>()
init {
list.addAll(initial)
}
override fun getItemCount(): Int {
return list.size
}
override fun createFragment(position: Int): Fragment {
return PageFragment.newInstance(list[position])
}
override fun getItemId(position: Int): Long {
return list[position].ordinal.toLong()
}
override fun containsItem(itemId: Long): Boolean {
return list.any { it.ordinal.toLong() == itemId }
}
fun updateList(newList: List<PageType>) {
// notifyDataSetChanged() だとうまく動かない
val diff = DiffUtil.calculateDiff(object : DiffUtil.Callback() {
override fun getOldListSize(): Int {
return list.size
}
override fun getNewListSize(): Int {
return newList.size
}
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return list[oldItemPosition] == newList[newItemPosition]
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return list[oldItemPosition] == newList[newItemPosition]
}
})
list.clear()
list.addAll(newList)
diff.dispatchUpdatesTo(this)
}
}
class PageFragment : Fragment() {
private val color = Color.rgb(Random.nextInt(256), Random.nextInt(256), Random.nextInt(256))
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return TextView(inflater.context).apply {
setBackgroundColor(color)
text = (requireArguments().getSerializable("type") as PageType).toString()
}
}
companion object {
fun newInstance(type: PageType): PageFragment {
return PageFragment().apply {
arguments = bundleOf("type" to type)
}
}
}
}
2021年2月25日木曜日
ViewPager2 でページを動的に追加・削除する
大事なポイントは FragmentStateAdapter を継承した Adapter で getItemId() と containsItem() を実装すること、notifyDataSetChanged() だとうまく動かないので DiffUtil.calculateDiff() を使うことです。
0 件のコメント:
コメントを投稿