Android Fragmentの中にタブ付きスワイプビューを作る（kotlin）

#はじめに
完成イメージはこんな感じ
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Android kotlin <br>fragmentの中にViewPageでスワイプできる画面を作る <a href="https://t.co/uayDvUnmIr">pic.twitter.com/uayDvUnmIr</a></p>&mdash; げん げんと (@gento34165638) <a href="https://twitter.com/gento34165638/status/1266981738284085254?ref_src=twsrc%5Etfw">May 31, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

「`BottomNavigationView`のボタンから遷移した先の、fragmentのページの中で、さらにfragmentで３つのページを作る」みたいな感じです。**（Androidネイティブ開発は初心者なので、文章がおかしいかもしれませんが、、、）**


##前提
すでに画面下の３つのタブがある状態。**このタブに作りかたについては、[こちら](https://www.youtube.com/watch?v=Chso6xrJ6aU)を参考に！（僕もこの動画を見ながら作りました。。）**
３つのタブは以下のようなFragmentを表示する。
・fragment_first.xml
・fragment_second.xml
・fragment_third.xml
<img width="436" alt="スクリーンショット 2020-05-31 16.09.45.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/f58a93d8-fac6-fc81-eda5-61ee63e7d4dc.jpeg">

[こちら](https://www.youtube.com/watch?v=Chso6xrJ6aU)と全く同じ作りにすると、`res/navigation/my_nav.xml`はこんな感じ。（secondFragmentの上部については、この記事でやっていきます:relieved:）
<img width="531" alt="スクリーンショット 2020-05-31 16.20.09.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/c28eb86d-19a2-c2d3-3b08-04faebe3a7b2.jpeg">

真ん中のsecondFragmentの中に、さらにスワイプ可能な３つのFragmentを作る。

#スワイプ可能な３つのFragmentを作る
`File>New>Fragment>Fragment(Blank)`より、３つ新たにFragmentを作成
<img width="867" alt="スクリーンショット 2020-05-31 18.45.11.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/6e066e2a-e6be-008f-1835-970a9bcd08b8.jpeg">

作るFragmentは以下の３つ
・`fragment_completed_.xml`
・`fragment_not_completed_.xml`
・`fragment_shared_.xml`

タブ付きスワイプビューのFragmentを作成するとこんな感じ。:point_down:
<img width="697" alt="スクリーンショット 2020-06-01 18.52.21.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/d067e672-cc8d-5940-4a9d-ba9b374804bc.jpeg">

#secondFragmentの上部に、TabLayoutとViewPagerを使ったタブ付きスワイプビューを作成する
一応公式ドキュメントは[こちら](https://developer.android.com/guide/navigation/navigation-swipe-view?hl=ja)（これを読んで実装できる初心者は、初心者ではない！）

<img width="743" alt="スクリーンショット 2020-05-31 18.56.37.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/49eb38c6-63f6-b608-7461-1438b024891a.jpeg">

```xml:fragment_second.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SecondFragment">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/pager"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tabLayout"
        app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <com.google.android.material.tabs.TabItem
            android:id="@+id/Not_Completed"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Not Completed" />

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

        <com.google.android.material.tabs.TabItem
            android:id="@+id/Shared"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Shared" />
    </com.google.android.material.tabs.TabLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
```

これで一旦見た目はできた。。


#スワイプビューの処理をするクラスを作る
`New>Kotlin File/Class`より**Fileを作成。**（クラスと言いつつFileを作る。。）
<img width="642" alt="スクリーンショット 2020-05-31 19.01.48.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/deddc831-6571-89b1-4fad-9ed3faba503e.jpeg">

<img width="392" alt="スクリーンショット 2020-05-31 19.01.31.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/de9c299e-4346-d7c8-41e7-ec9edb8136f5.jpeg">

```kotlin:PageAdapter.kt
package com.example.myapplication

import android.content.Context
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import com.example.myapplication.completed_Fragment
import com.example.myapplication.not_completed_Fragment
import com.example.myapplication.shared_Fragment


class PageAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {
    override fun getItem(position: Int): Fragment {
        when (position) {
          // どのFragmentを表示するか
            0 -> {return  not_completed_Fragment()}
            1 -> {return  completed_Fragment()}
            2 -> {return  shared_Fragment()}
            else -> {return  not_completed_Fragment()}
        }
    }

// スワイプビューの数が３つだから
    override fun getCount(): Int {
        return 3;
    }

// スワイプビューのタイトルを決める
    override fun getPageTitle(position: Int): CharSequence? {
        when(position){
            0 -> {return "Not Completed"}
            1 -> {return  "Completed"}
            2 -> {return "Shared"}
            else -> {return null}
        }
    }
}
```

#secondFragmentでタブ付きスワイプビューを動作するようにする


```kotlin:SecondFragment.kt
package com.example.myapplication

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.viewpager.widget.ViewPager
import kotlinx.android.synthetic.main.fragment_second.*


/**
 * A simple [Fragment] subclass.
 */
class SecondFragment : androidx.fragment.app.Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?

    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_second, container, false)
    }

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

        // ActionBarを隠す
        (activity as AppCompatActivity).supportActionBar?.hide()

        val fragmentManager = (activity as FragmentActivity).supportFragmentManager

       //ここの「pager」はfragment_second.xmlのViewPagerのidの事！
        pager.adapter = PageAdapter(fragmentManager)
        tabLayout.setupWithViewPager(pager)
    }
}
```

この時点で**恐らくタブ付きスワイプビューは動作するかと。。。。**

#fragment_firstとfragment_thirdで、タイトルバーが再表示されるようにする
・fragment_first.xml
・fragment_second.xml
・fragment_third.xml
<img width="436" alt="スクリーンショット 2020-05-31 16.09.45.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/f58a93d8-fac6-fc81-eda5-61ee63e7d4dc.jpeg">

こちらの３つのFragmentだが、`SecondFragment.kt`の`onViewCreated`の関数で、タイトルバーを隠すようしているので、他のFragmentでは再表示させないといけません。

```kotlin:SecondFragment.kt
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // ActionBarを隠す
        (activity as AppCompatActivity).supportActionBar?.hide()

        val fragmentManager = (activity as FragmentActivity).supportFragmentManager

       //ここの「pager」はfragment_second.xmlのViewPagerのidの事！
        pager.adapter = PageAdapter(fragmentManager)
        tabLayout.setupWithViewPager(pager)
    }
}
```

なので、`FirstFragment.kt`と`thirdFragment.kt`を以下のようにする

```kotlin
package com.example.myapplication

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity

/**
 * A simple [Fragment] subclass.
 */
class FirstFragment : androidx.fragment.app.Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_first, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // ActionBarを出す
        (activity as AppCompatActivity).supportActionBar?.show()
    }
}
```

#最後に
Fragmentの中に、さらにFragmentを作って表示、と言うのがなかなか情報がなく、苦戦しました。。。
**`onViewCreated`の関数が重要なようです！**