【Jetpack】ナビゲーションナビゲーションコンポーネント② (ナビゲーションコアポイントの説明 | ナビゲーショングラフの作成 | NavHostFragmentの作成 | 完全なコード例 )


コードアドレス:





1. ナビゲーション ナビゲーション コンポーネント開発の核心ポイントの説明




1. Navigationの各サブコンポーネントの作成順序


Navigation ナビゲーション コンポーネントの各サブコンポーネントの作成順序の主なポイントは次のとおりです。

  • まず、ナビゲートされるフラグメント ページのコードと、対応するレイアウト ファイルを作成します。
  • 次に、作成された Fragment に基づいて対応するナビゲーション グラフを作成し、その中の Fragment 間のジャンプ アクションを構成します。
  • 次に、作成された Navigation Graph に基づいてコンテンツを表示する NavHostFragment コンポーネントを作成します。
  • 最後に、アクティビティで NavController コンポーネントを取得して、フラグメント間のジャンプを実現します。

上記のプロセスに従って作成する必要があります: Fragment -> Navigation Graph -> NavHostFragment -> NavController 。後者のコンポーネントは前のコンポーネントに依存します。そうしないと、Navigation ナビゲーションを実現できません。


2. ナビゲーションの依存関係をインポートする


Navigation コンポーネントを使用するには、Navigation の依存関係をインポートする必要があり、異なる開発言語は異なる依存関係をインポートします。

  • Java 言語使用してナビゲーション ナビゲーションを開発し、次の依存関係をインポートします。
dependencies {
    
      
    implementation 'androidx.navigation:navigation-fragment:2.2.2'
    implementation 'androidx.navigation:navigation-ui:2.2.2'
}
  • Kotlin言語を使用してナビゲーション ナビゲーションを開発し、次の依存関係をインポートします。
dependencies {
    
      
    implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0'  
    implementation 'androidx.navigation:navigation-ui-ktx:2.3.0'  
}

依存関係をインポートせずにナビゲーションを直接使用すると、「ナビゲーション依存関係の追加に失敗しました」という例外メッセージが報告されます。


3. フラグメントファイルとレイアウトファイルを作成する


コード パッケージを右クリックしてフラグメントを作成し、[新規 / フラグメント / フラグメント (空白)] オプションを選択すると、フラグメントを直接作成して、対応するフラグメント レイアウト ファイルを生成できます。

ここに画像の説明を挿入


4.ナビゲーショングラフの作成


res リソース ディレクトリを右クリックし、ポップアップ ドロップダウン メニューで[新規 / Android リソース ファイル] オプションを選択します。

ここに画像の説明を挿入
「リソースタイプ」オプションで「ナビゲーション」オプションを選択します。選択後、「ルート要素」と「ディレクトリ名」オプションが自動的に設定されます。開発者は「ファイル名」を設定するだけで済みます。

ここに画像の説明を挿入
ナビゲーション グラフを作成するときは、ナビゲーション管理にどのフラグメントを含めるかを指定する必要があります。そのため、最初にフラグメントを作成してからナビゲーション グラフを作成する必要があります。

ナビゲーション グラフを作成した後、デザイン モードで[新しい宛先] ボタンをクリックして、ナビゲーションするフラグメント ページを追加します。フラグメント A とフラグメント B の両方がナビゲーション ナビゲーション管理に含まれます。

ここに画像の説明を挿入

作成後、マウスをドラッグしてナビゲーション グラフ内の 2 つのフラグメント間のジャンプ関係を設定できます。フラグメント A はフラグメント B にジャンプし、フラグメント B はフラグメント A にジャンプします。

ここに画像の説明を挿入

このようにして、ナビゲーション グラフの作成が完了します。次に、上記の 2 つのジャンプが NavController を通じて呼び出され、2 つのフラグメント間のジャンプがそれぞれ実現されます。


5. NavHost フラグメントの作成


NavHostFragment はアクティビティのレイアウト ファイルに設定されます。<fragment/>通常android:name="androidx.navigation.fragment.NavHostFragment"、プロパティはラベルに設定され、フラグメントは NavHostFragment になります。

    <fragment
        android:id="@+id/fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/navigation_graph" />

コンテナの下の NavHostFragment をデザイン グラフィカル インターフェイスのレイアウトにドラッグすることはお勧めできません。生成されたコードは間違っています。

特定のエラーの内容は、エラー レコードの列で詳細に分析されるため、ここでは繰り返しません。
ここに画像の説明を挿入


6.NavControllerの作成


Activity で findNavController 関数を呼び出してNavController を取得し、 NavController 変数内を移動します。

FragmentContainerView コンポーネントの管理操作は、NavController を通じて行われます。

        // fragmentContainerView 组件的 管理 操作通过 NavController 完成
        // 对应的就是 navController 实例变量
        val navController = findNavController(this, R.id.fragment)
        NavigationUI.setupActionBarWithNavController(this, navController)

7. ナビゲーション操作を実現するフラグメント


Fragment インターフェースで、ボタンをクリックして別の Fragment インターフェースにジャンプします。

まず、 NavigationController を取得し、Navigation.findNavController 関数を呼び出してNavigationController インスタンス オブジェクトを取得します。

次に、 NavigationController#navigate を呼び出してナビゲートし、ナビゲーション グラフ内の特定のアクションの ID を渡します。

            // 获取 NavigationController
            val navController = Navigation.findNavController(it)
            // 按照 action_fragmentA_to_fragmentB 对应的 action 的导航路线走
            navController.navigate(R.id.action_fragmentA_to_fragmentB)

上記のコードのR.id.action_fragmentA_to_fragmentB対応する次のとおりです。

    <fragment
        android:id="@+id/fragmentA"
        android:name="kim.hsl.nav.FragmentA"
        android:label="fragment_a"
        tools:layout="@layout/fragment_a" >
        <action
            android:id="@+id/action_fragmentA_to_fragmentB"
            app:destination="@id/fragmentB" />
    </fragment>




2. Navigation ナビゲーション コンポーネントの完全なコード例



コードアドレス:


1. 完全なソースコードを断片化する


2 つのフラグメントを作成し、各フラグメントにボタンを設定して、2 つのフラグメント間をジャンプします。

フラグメントAのソースコード

Fragment のコア ジャンプ ソース コードは次のとおりです。最初に NavigationController を取得し、次に NavigationController#navigate を呼び出して FragmentB ページにジャンプします。

            // 获取 NavigationController
            val navController = Navigation.findNavController(it)
            // 按照 action_fragmentA_to_fragmentB 对应的 action 的导航路线走
            navController.navigate(R.id.action_fragmentA_to_fragmentB)

完全なソースコード:

package kim.hsl.nav

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.fragment.app.Fragment
import androidx.navigation.Navigation
import androidx.navigation.Navigation.findNavController

// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

/**
 * A simple [Fragment] subclass.
 * Use the [FragmentA.newInstance] factory method to
 * create an instance of this fragment.
 */
class FragmentA : Fragment() {
    
    
    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private var param2: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        arguments?.let {
    
    
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

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

    companion object {
    
    
        /**
         * Use this factory method to create a new instance of
         * this fragment using the provided parameters.
         *
         * @param param1 Parameter 1.
         * @param param2 Parameter 2.
         * @return A new instance of fragment FragmentA.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            FragmentA().apply {
    
    
                arguments = Bundle().apply {
    
    
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    
    
        super.onViewCreated(view, savedInstanceState)
        val button = view.findViewById<Button>(R.id.button)
        button.setOnClickListener {
    
    
            // 获取 NavigationController
            val navController = Navigation.findNavController(it)
            // 按照 action_fragmentA_to_fragmentB 对应的 action 的导航路线走
            navController.navigate(R.id.action_fragmentA_to_fragmentB)
        }
    }
}

FragmentA レイアウト ファイル

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FragmentA">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="跳转到 B"
        android:onClick="onClick" />

</FrameLayout>

フラグメントBのソースコード

Fragment のコア ジャンプ ソース コードは次のとおりです。最初に NavigationController を取得し、次に NavigationController#navigate を呼び出して FragmentB ページにジャンプします。

            // 获取 NavigationController
            val navController = Navigation.findNavController(it)
            // 按照 action_fragmentB_to_fragmentA 对应的 action 的导航路线走
            navController.navigate(R.id.action_fragmentB_to_fragmentA)

完全なコードは次のとおりです。

package kim.hsl.nav

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.navigation.Navigation

// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

/**
 * A simple [Fragment] subclass.
 * Use the [FragmentB.newInstance] factory method to
 * create an instance of this fragment.
 */
class FragmentB : Fragment() {
    
    
    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private var param2: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        arguments?.let {
    
    
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

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

    companion object {
    
    
        /**
         * Use this factory method to create a new instance of
         * this fragment using the provided parameters.
         *
         * @param param1 Parameter 1.
         * @param param2 Parameter 2.
         * @return A new instance of fragment FragmentB.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            FragmentB().apply {
    
    
                arguments = Bundle().apply {
    
    
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    
    
        super.onViewCreated(view, savedInstanceState)
        val button = view.findViewById<Button>(R.id.button)
        button.setOnClickListener {
    
    
            // 获取 NavigationController
            val navController = Navigation.findNavController(it)
            // 按照 action_fragmentB_to_fragmentA 对应的 action 的导航路线走
            navController.navigate(R.id.action_fragmentB_to_fragmentA)
        }
    }
}

FragmentB レイアウト ファイル

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FragmentB">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="跳转到 A"
        android:onClick="onClick" />

</FrameLayout>

2. ナビゲーション グラフのソース コード


ナビゲーション グラフを作成し、2 つのフラグメントをインポートし、ナビゲーション グラフ内の 2 つのフラグメント間のジャンプ関係を設定します。フラグメント A はフラグメント B にジャンプし、フラグメント B はフラグメント A にジャンプします。

<?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/navigation_graph"
    app:startDestination="@id/fragmentA">

    <fragment
        android:id="@+id/fragmentA"
        android:name="kim.hsl.nav.FragmentA"
        android:label="fragment_a"
        tools:layout="@layout/fragment_a" >
        <action
            android:id="@+id/action_fragmentA_to_fragmentB"
            app:destination="@id/fragmentB" />
    </fragment>
    <fragment
        android:id="@+id/fragmentB"
        android:name="kim.hsl.nav.FragmentB"
        android:label="fragment_b"
        tools:layout="@layout/fragment_b" >
        <action
            android:id="@+id/action_fragmentB_to_fragmentA"
            app:destination="@id/fragmentA" />
    </fragment>
</navigation>

3. NavHostFragment コンポーネントをアクティビティ レイアウト ファイルに追加します。


NavHostFragment はアクティビティのレイアウト ファイルに設定されます。<fragment/>通常android:name="androidx.navigation.fragment.NavHostFragment"プロパティはラベルに設定され、フラグメントは NavHostFragment になります。

    <fragment
        android:id="@+id/fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/navigation_graph" />

完全なレイアウト ファイルのコードは次のとおりです。

<?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=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <fragment
        android:id="@+id/fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/navigation_graph" />

</androidx.constraintlayout.widget.ConstraintLayout>

4.アクティビティコードでNavControllerを取得し、ナビゲートします。


アクティビティで findNavController 関数を呼び出して NavController を取得し、NavController 変数内を移動します。

FragmentContainerView コンポーネントの管理操作は、NavController を通じて行われます。

        // fragmentContainerView 组件的 管理 操作通过 NavController 完成
        // 对应的就是 navController 实例变量
        val navController = findNavController(this, R.id.fragment)
        NavigationUI.setupActionBarWithNavController(this, navController)

完全なコードは次のとおりです。

package kim.hsl.nav

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.Navigation.findNavController
import androidx.navigation.ui.NavigationUI

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

        // fragmentContainerView 组件的 管理 操作通过 NavController 完成
        // 对应的就是 navController 实例变量
        val navController = findNavController(this, R.id.fragment)
        NavigationUI.setupActionBarWithNavController(this, navController)
    }
}

5. 運用効果


FragmentA ページのボタンをクリックすると FragmentB ページに移動し、FragmentB ページのボタンをクリックすると FragmentA ページに移動します。

画像の説明を追加してください


コードアドレス:

おすすめ

転載: blog.csdn.net/han1202012/article/details/131299078