ZOZOのアプリのUIを再現しようの会  【お気に入りタブ編】その１

##はじめに
知り合いのAndroidエンジニア方たちとZOZOTOWNのアプリのUIを再現しようというハッカソン的なことを始めました。そこで実装していく上で考えたことや詰まったことなどを何回かに分けて記事として投稿していこうかなと思います。

ZOZOTOWNのアプリは画面下に5つのタブがついています(著作権的なことが怖いので画像は載せません🙇‍♂️)。今回は一人が一つのタブ毎の画面を担当するという構成になりました。僕はお気に入りタブの担当になったので、お気に入りタブに関して書いていきます！

今回はTabLayoutとViewPager2の接続部分をやっていこうと思います。

##今回の完成像

<img width="400" alt="今回の完成像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092570/4165fd2c-b030-6ed8-2609-7592ff57a3e3.gif">

##全体の構成
TabLayout + ViewPager2 + FragmentStateAdapterという構成になっています。下のタブ毎にFragmentを持っています。お気に入りのFragment(以下FavoriteFragment)の内部で、新着、アイテム、ブランド、のタブ毎に子Fragmentを１つずつ持ってそれをViewPager2で切り替えるという実装になっています。

TabLayoutMediatorの部分でTabLayoutとViewPager２を接続しています。

##全体のコード
FavoriteFragmentのコード全体です。

```kotlin
class FavoriteFragment : Fragment() {
    private var _binding: FragmentFavoriteBinding? = null
    private val binding: FragmentFavoriteBinding
        get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentFavoriteBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val adapter = FavoriteViewPagerAdapter(this)
        setUpViewPager2(adapter)
        connectTabLayoutAndViewPager2()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    private fun setUpViewPager2(adapter: FavoriteViewPagerAdapter) {
        binding.favoriteViewPager.adapter = adapter
    }

    private fun connectTabLayoutAndViewPager2() {
        TabLayoutMediator(binding.favoriteTabLayout, binding.favoriteViewPager) { tab, position ->
            val tabTitle = when (position) {
                FragmentsOrder.NEW_ITEM.ordinal -> FragmentsOrder.NEW_ITEM.title
                FragmentsOrder.ITEM.ordinal -> FragmentsOrder.ITEM.title
                FragmentsOrder.BRAND.ordinal -> FragmentsOrder.BRAND.title
                else -> ""
            }
            tab.text = tabTitle
        }.attach()
    }

    private class FavoriteViewPagerAdapter(parentFragment: Fragment) : FragmentStateAdapter(parentFragment) {
        override fun getItemCount(): Int = FragmentsOrder.values().size
        override fun createFragment(position: Int): Fragment {
            return when (position) {
                FragmentsOrder.NEW_ITEM.ordinal -> FavoriteNewItemFragment.newInstance()
                FragmentsOrder.ITEM.ordinal -> FavoriteItemFragment.newInstance()
                FragmentsOrder.BRAND.ordinal -> FavoriteBrandFragment.newInstance()
                else -> throw IllegalArgumentException("予想外のFragmentです")
            }
        }
    }

    private enum class FragmentsOrder(val title: String) {
        NEW_ITEM("新着"), ITEM("アイテム"), BRAND("ブランド")
    }
}
```

##終わりに
次はFavoriteFragmentのお気に入りタブの下の部分をRecyclerViewで実装していきます！

##次の記事
https://qiita.com/nemo-855/items/81269ebb70295fb44e31

##ハッカソンのメンバー
レビュアー: どすこいさん
https://twitter.com/dosukoi_android

ホームタブ担当(&主催): みっちゃんさん
https://twitter.com/mimimi_engineer

探すタブ担当: らべさん
https://twitter.com/wawatantanwawa

他２人

##リポジトリ
https://github.com/iroha-168/AndroidUITrain

##参考文献
https://developer.android.com/training/animation/screen-slide-2

https://developer.android.com/reference/androidx/viewpager2/adapter/FragmentStateAdapter

https://developer.android.com/reference/com/google/android/material/tabs/TabLayoutMediator