LoginSignup
12
11

More than 1 year has passed since last update.

Fragment間の画面遷移

Last updated at Posted at 2023-03-21

はじめに

今回はFragment間の画面遷移について書いていこうと思います。
Fragment間の画面遷移は2つの方法があるのでそれぞれ実装方法を記載します。

サンプル画面イメージ

画面にボタンがあり、タップすると別のFragmentへ画面遷移します。

FragmentA FragmentB

1. FragmentManagerを使用した場合の実装

FragmentManger
アプリのフラグメントに対するアクション(フラグメントの追加、削除、置換、バックスタックへの追加など)を実行するためのクラスになります。
Fragmentの1連の処理(トランザクション)をコミットすることでフラグメントをバックスタックへ追加・削除・置換などをすることができます。
FragmentManagerを取得するメソッドはActivityとFragmentで異なります。

実装箇所 メソッド
Activity getSupportFragmentManager()
Fragment getParentFragmentManager()

https://developer.android.com/guide/fragments/fragmentmanager?hl=ja

実装

MainActivity.kt
class MainActivity : AppCompatActivity() {
    // FragmentManagerの取得
    private val fm = supportFragmentManager

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

        // トランザクションの生成・コミット
        fm.beginTransaction().apply {
            replace(R.id.fragment_container, FragmentA())
            commit()
        }
    }
}
FragmentA.kt
class FragmentA : Fragment() {

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

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

        val button = view.findViewById<Button>(R.id.button)
        button.setOnClickListener {
            // FragmentManagerの取得
            val pfm = parentFragmentManager

            // トランザクションの生成・コミット
            val ft = pfm.beginTransaction()
            ft.apply {
                replace(R.id.fragment_container, FragmentB())
                commit()
            }
        }
    }
}

// FragmentBも同様の処理のため省略

以上でFragmentManagerによる画面遷移が可能になります。

2. NavigationComponentを使用した場合の実装

NavigationComponent
Android Jetpackのコンポーネントの一つでナビゲーションの実装が簡単にできるようになります。
単純なアプリバーやナビゲーションドロワーなどの実装をするのにも役立ちます。
前述でFragmentManagerによる遷移を説明しましたがNavigationComponentの使用が推奨されています。

https://developer.android.com/guide/navigation?hl=ja

Navigationコンポーネントには以下三つの要素があります。

要素 機能
ナビゲーショングラフ ナビゲーションの情報を保管するXMLファイル
NavHost Fragmentを表示するコンテナ
NavController ナビゲーションを管理するオブジェクト

実装

1.build.gradleへ追加
Navigation Componentを使用するにはプロジェクトにコンポーネントを追加する必要があります。

build.gradle
def nav_version = "2.5.3"

// Kotlin
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

// Dynamic Feature Module Support
implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"

2.ナビゲーショングラフの追加
resourceフォルダに[resouces type]をNavigationで新規ファイル追加します。

nav_graph.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/nav_graph">

</navigation>

3.NavHostの設定
NavHostの実装はNavHostFragmentをActivityに追加することで実装が可能です。
xmlのFragmentContainerViewのandroid:name属性にNavHostFragmentを設定します。

activity_main.xml
<androidx.fragment.app.FragmentContainerView
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    app:defaultNavHost="true"
    app:navGraph="@navigation/nav_graph"
    />

その他FragmentContainerViewの設定値は以下公式を参照ください。

https://developer.android.com/guide/navigation/navigation-getting-started?hl=ja#add-navhostfragment

4.ナビゲーショングラフにデスティネーションを設定する
app:startDestinationはアプリ開始時に表示されるFragmentを設定します。

nav_graph.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation
    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:id="@+id/nav_graph"
    app:startDestination="@id/FragmentA"
    >

    <fragment
        android:id="@+id/FragmentA"
        android:name="com.example.navigationsample.fragment.FragmentA"
        android:label="fragmentA"
        tools:layout="@layout/fragment_a" />

    <fragment
        android:id="@+id/FragmentB"
        android:name="com.example.navigationsample.fragment.FragmentB"
        android:label="fragmentB"
        tools:layout="@layout/fragment_b" />

</navigation>

5.デスティネーションに移動する
actionを記載することでナビゲーショングラフに遷移情報を設定することができます。
navHostが持つNavControllerを取得し、ナビゲーショングラフで設定したactionを呼ぶことができます。

nav_graph.xml
<!-- FragmentAにFragmentBへの遷移情報を設定 -->
<fragment
    android:id="@+id/FragmentA"
    android:name="com.example.navigationsample.fragment.FragmentA"
    android:label="fragmentA"
    tools:layout="@layout/fragment_a">

    <action
        android:id="@+id/action_FragmentA_to_FragmentB"
        app:destination="@id/FragmentB" />

</fragment>
FragmentA.kt
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    val button = view.findViewById<Button>(R.id.button)
    button.setOnClickListener {
        // NavControllerを取得
        val navController = view.findNavController()

        // 画面遷移
        navController.navigate(R.id.action_FragmentA_to_FragmentB)
    }
}

NavControllerの取得方法はいくつかあるので以下の記事を参照ください。

https://developer.android.com/guide/navigation/navigation-getting-started?hl=ja#navigate

以上で画面遷移が可能になります。

終わりに

最後まで読んでいただきありがとうございます!

今回は基本的Fragment間の画面遷移を記載しました。
他にもデータの受け渡しやDrawer, Bottom Navigationなど実際のアプリ開発でよく使用するパターンもあるので別の記事で記載していけたらと思います。

12
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
11