【Android Studio】Fragmentの実装と遷移の方法

#はじめに
最近、Android Studioについての学習を始めて躓いたFragmentについて備忘録もかねて記事を書こうと思います。
使用したAndroid Studioのバージョンは4.2.2、
OSはWindows10を使用しています。

#目次
- [Fragmentとは？](#fragmentとは)
- [Fragmentの実装](#fragmentの実装)
- [Fragmentの遷移](#fragmentの遷移)
- [最後に](#最後に)

#Fragmentとは？
Androidアプリに表示される一つ一つの画面をActivityと呼ぶ。
FragmentとはそのActivityの上に載っている部品のことを指しており、画面の一部分に独立した動きをさせることができる。
Activityが呼び出すFragmentを変えることで、画面の一部のみを変化させることが可能になる。
また、FragmentはActivityとは異なった独自のライフサイクルを持っている。

#Fragmentの実装
ここからはFragmentの実装手順についてシンプルな方法をまとめておく。
今回は例としてまず以下のようなテキストビューしか配置していないメインアクティビティを用意した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1767634/b21c670b-ae4e-5b94-71b8-893957a3fb92.png)

####(1) ファイル一覧の部分で右クリック→「New」→「Fragment」→「Gallery...」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1767634/008851b4-8e05-3953-5611-eeb36c46e24f.png)

####(2) 好きな種類のFragmentを選択して「Next」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1767634/fb169a11-17b4-fcd9-7b9f-bec4e36ca347.png)

####(3) 以下の項目を入力して「Finish」

- Java(Kotlin)ソースコードファイルの名前
- Fragmentのレイアウトファイルの名前
- ソースコードの言語

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1767634/a2d37579-c8e3-4068-8d5d-b83183143b88.png)
これでFragmentを追加することができる。
例ではFragmentのレイアウトを以下のようにしてみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1767634/1f70aa77-b145-9729-68e2-549c6e6722d9.png)

とりあえずこのまま実際のアプリの画面を見てみると…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1767634/ac496337-5cfb-e7c8-c744-fd5942be2f84.png)
↑このように、メインアクティビティが表示されるだけで画面にFragmentは表示されない。
　表示させるためにもう少し手を加えないといけない。

####(4) Fragmentを表示するためのレイアウトをActivityに配置する。(Fragmentのコンテナ)
配置するレイアウトは`<LinearLayout>`, `<RelativeLayout>`, `<FrameLayout>`どれでもOK
紹介する例では`<FrameLayout>`を使用した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1767634/e912c27d-b222-ea4b-e338-3e021e042d02.png)

####(5) メインアクティビティのソースコードにFragmentを呼び出すための記述をする。

```MainActivity.kt

package com.example.fragmenttest

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Fragmentを追加した際に生成されたクラスを呼びだす //
        val mainfragment = main()
        
        // FragmentManagerを使うことでFragmentの追加や削除などの制御を行うことができる //
        val transaction = supportFragmentManager.beginTransaction()
        
        // addメソッドで"どこ"に"どの"Fragmentを追加するのかを決める //
        transaction.add(R.id.FragmentContainer, mainfragment)
        
        //commitメソッドで追加したメソッドを反映する //
        transaction.commit()
    }
}
```
とりあえずこれだけ記述すればFragmentが表示されるはず。
実際に確認してみると…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1767634/d1b5a9a9-b603-a548-18f7-8a6907ed03e2.png)
↑このようにメインアクティビティ上にFragmentが表示された。

#Fragmentの遷移
ここまででFragmentの実装はできるようになったので、
次にFragment間の遷移方法についても簡単にまとめていこうと思う。
Fragmentを二つ用意し、一つ目のFragmentに配置されたボタンを押下すると二つ目のFragmentに遷移するような処理をつける。
さらに、二つ目のFragmentに配置されたボタンを押下すると一つ目のFragmentに戻るような処理もつける。
今回例として以下の二つのFragmentを用意した。


・一つ目のActivity：fragment_main
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1767634/6acf047a-0e5d-7823-5e52-198c5e577e21.png "main")

・二つ目のActivity：fragment_sub
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1767634/2c08b8b7-46f9-a648-0fb4-09082b3a9fc3.png "sub")

それぞれのFragmentのレイアウトができたら、次にボタンを押下した時の処理を記述していく。

一つ目のFragmentにある「GotosubButton」を押下したら二つ目のFragmentに遷移するようなコードを記述する。
以下にコードを抜粋。

```main.kt

class main : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_main, container, false)
    }

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

        // FragmentManagerを用意 //
        val transaction = parentFragmentManager.beginTransaction()

        // fragment_mainに配置してあるボタン //
        val gotosubButton = view.findViewById<Button>(R.id.GotosubButton)

        // ボタンを押下されたときのイベントを記述する //
        gotosubButton.setOnClickListener {
            // 遷移先のFragmentのクラスを呼び出す //
            val subfragment = sub()

            // 今のFragmentをスタックしておくことで遷移先から戻るボタンでもどれるようにする //
            transaction.addToBackStack(null)

            // R.id.FragmentContainerに入っているFragmentを取り除いて、新しく別のFragmentを入れる //
            transaction.replace(R.id.FragmentContainer, subfragment)
            transaction.commit()
        }
    }
}

```
ここまで記述できれば一つ目のFragmentのボタンを押下すると二つ目のFragmentに遷移するはず。
あとは二つ目のFragmentに配置した「ReturnButton」を押下した時に前のFragmentに戻る処理を記述すれば完成。
以下にその部分のコードを抜粋。

```sub.kt

class sub : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_sub, container, false)
    }

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

        // Sub Fragmentに配置してあるボタン //
        val returnButton = view.findViewById<Button>(R.id.ReturnButton)

        // ボタンを押下されたときのイベントを記述する //
        returnButton.setOnClickListener {

            // Fragmentを一つ前の状態に戻す //
            parentFragmentManager.popBackStack()
        }
    }
}

```
ここまで記述できれば二つのFragment間を遷移できるようになっているはず。
実際にエミュレータで確認してみると…
![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1767634/2322f5f3-85e8-6241-913c-6638ec913ce9.gif)
↑このようにFragmentの遷移を実装することができた。

#最後に
Android Studioを触ったばかりでFragmentとはどういうものなのか、どうやって導入するのかという超初歩的なところから躓いたので、なるべく小難しいことなどは抜きにして記事を書いてみました。
自分のような初心者にとって少しでも役に立てば幸いです。

#参考

http://memento-mori-blog.com/android-kotlin-fragment/

https://calculus-app.com/blog/develop_android/android_fragment/201