コードアドレス:
- CSDN (このブログのコード スナップショット | 推奨ダウンロード 0 クレジット): https://download.csdn.net/download/han1202012/87936252
- GitHub (カバーされている可能性があります): https://github.com/han1202012/Navigation
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 ナビゲーション コンポーネントの完全なコード例
コードアドレス:
- CSDN (このブログのコード スナップショット | 推奨ダウンロード 0 クレジット): https://download.csdn.net/download/han1202012/87936252
- GitHub (カバーされている可能性があります): https://github.com/han1202012/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 ページに移動します。
コードアドレス:
- CSDN (このブログのコード スナップショット | 推奨ダウンロード 0 クレジット): https://download.csdn.net/download/han1202012/87936252
- GitHub (カバーされている可能性があります): https://github.com/han1202012/Navigation