Android - Navigation组件

Navigation 组件使用入门

设置你的环境

注意:Navigation 组件需要 Android Studio 3.3 或更高版本,并且依赖于 Java 8 语言功能。

如需在您的项目中添加 Navigation 支持,请向应用的 build.gradle 文件添加以下依赖项:

dependencies {
  def nav_version = "2.4.2"
  // Java language implementation
  implementation "androidx.navigation:navigation-fragment:$nav_version"
  implementation "androidx.navigation:navigation-ui:$nav_version"
  // Kotlin
  implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
  implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
  // Feature module Support
  implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"
  // Testing Navigation
  androidTestImplementation "androidx.navigation:navigation-testing:$nav_version"
  // Jetpack Compose Integration
  implementation "androidx.navigation:navigation-compose:$nav_version"
}

导航图使用

创建导航图

  1. 在“Project”窗口中,右键点击 res 目录,然后依次选择 New > Android Resource File。此时系统会显示 New Resource File 对话框。
  2. File name 字段中输入名称,例如“nav_graph”。
  3. Resource type 下拉列表中选择 Navigation,然后点击 OK

当您添加首个导航图时,Android Studio 会在 res 目录内创建一个 navigation 资源目录。该目录包含您的导航图资源文件(例如 nav_graph.xml)。

添加图表后,Android Studio 会在 Navigation Editor 中打开该图表。在 Navigation Editor 中,您可以直观地修改导航图,或直接修改底层 XML。

向导航图中添加目的地

  • 在 Navigation Editor 中,点击 New Destination 图标 ,然后点击 Create new destination。
  • 在随即显示的 New Android Component 对话框中,创建您的 Fragment。
<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/my_nav"
    app:startDestination="@id/homeFragment">

    <fragment
        android:id="@+id/homeFragment"
        android:name="com.example.navigation.HomeFragment"
        android:label="Home"
        tools:layout="@layout/fragment_home">
    </fragment>
</navigation>
  • Type 字段指示在您的源代码中,该目的地是作为 fragment、activity 还是其他自定义类实现的。

  • Label 字段包含该目的地的用户可读名称。例如,如果您使用 setupWithNavController() 将 NavGraph 连接到 Toolbar,就可能在界面上看到此字段。因此,我们建议您对此值使用资源字符串。

  • ID 字段包含该目的地的 ID,它用于在代码中引用该目的地。

将某个屏幕指定为起始目的地

起始目的地是用户打开您的应用时看到的第一个屏幕,也是用户退出您的应用时看到的最后一个屏幕。Navigation Editor 使用房子图标表示起始目的地。

所有目的地就绪后,您便可以选择起始目的地,具体操作步骤如下:

  1. Design 标签页中,点击相应目的地,使其突出显示。
  2. 点击 Assign start destination 按钮 。或者,您可以右键点击该目的地,然后点击 Set as Start Destination

连接目的地

AS 上边有教程

完成之后,切换到 XML 视图。现在,一个 action 元素已添加到源目的地中。该操作有一个 ID 和一个目的地属性(其中包含下一个目的地的 ID),如以下示例所示:

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

    <fragment
        android:id="@+id/homeFragment"
        android:name="com.example.navigation.HomeFragment"
        android:label="Home"
        tools:layout="@layout/fragment_home">
        <action
            android:id="@+id/action_homeFragment_to_detailFragment"
            app:destination="@id/detailFragment" />
    </fragment>

    <fragment
        android:id="@+id/detailFragment"
        android:name="com.example.navigation.DetailFragment"
        android:label="Detail"
        tools:layout="@layout/fragment_detail">
        <action
            android:id="@+id/action_detailFragment_to_homeFragment"
            app:destination="@id/homeFragment" />
    </fragment>
</navigation>

向 Activity 添加 NavHost

导航宿主(NavHost) 是 Navigation 组件的核心部分之一。导航宿主是一个空容器,用户在您的应用中导航时,目的地会在该容器中交换进出。

通过 XML 添加 NavHostFragment
以下 XML 示例显示了作为应用主 Activity 一部分的 NavHostFragment:

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

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragmentContainerView"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/my_nav" />

</androidx.constraintlayout.widget.ConstraintLayout>

请注意以下几点:

  • android:name 属性包含 NavHost 实现的类名称。
  • app:navGraph 属性将 NavHostFragment 与导航图相关联。导航图会在此 NavHostFragment 中指定用户可以导航到的所有目的地。
  • app:defaultNavHost=“true” 属性确保您的 NavHostFragment 会拦截系统返回按钮。请注意,只能有一个默认 NavHost。如果同一布局(例如,双窗格布局)中有多个宿主,请务必仅指定一个默认 NavHost。

您也可以使用布局编辑器向 Activity 添加 NavHostFragment,具体操作步骤如下:

  1. 在项目文件列表中,双击 Activity 的布局 XML 文件,以在 Layout Editor 中将其打开。
  2. Palette 窗格内,选择 Containers 类别,或者搜索“NavHostFragment”。
  3. NavHostFragment 视图拖动到您的 Activity 上。
  4. 接下来,在随即显示的 Navigation Graphs 对话框中,选择需要与此 NavHostFragment 相关联的相应导航图,然后点击 OK

导航到目的地

导航到目的地是使用 NavController 完成的,它是一个在 NavHost 中管理应用导航的对象。每个 NavHost 均有自己的相应 NavController

在对应的 Fragment 中完成对应的跳转逻辑:

	@Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) 	{
        super.onViewCreated(view, savedInstanceState);
        // 第一种写法
        view.findViewById(R.id.homeButton).setOnClickListener(view1 -> {
            NavController controller = Navigation.findNavController(view);
            controller.navigate(R.id.action_homeFragment_to_detailFragment);
        });
    }
   
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        // 第二种写法
        view.findViewById(R.id.detail_button).setOnClickListener(
                Navigation.createNavigateOnClickListener(R.id.action_detailFragment_to_homeFragment));
    }

完成跳转逻辑之后就可以正常运行了。

右上角返回按钮的实现

在 Activity 中完成以下逻辑:

		NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragmentContainerView);
        NavController controller = navHostFragment.getNavController();
        NavigationUI.setupActionBarWithNavController(this, controller);

这部分只能将按钮显示出来。
为了实现返回功能,还要重写 onSupportNavigateUp() 方法:

	@Override
    public boolean onSupportNavigateUp() {
        //return super.onSupportNavigateUp();
        NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragmentContainerView);
        NavController controller = navHostFragment.getNavController();
        return controller.navigateUp();
    }

传递数据

定义目的地参数:

如需在目的地之间传递数据,首先请按照以下步骤将参数添加到接收它的目的地来定义参数:

  • 在 Navigation Editor 中,点击接收参数的目的地。
  • Attributes 面板中,点击 Add (+)
  • 在显示的 Add Argument Link 窗口中,输入参数名称、参数类型、参数是否可为 null,以及默认值(如果需要)。
  • 点击 Add。请注意,该参数现在会显示在 Attributes 面板的 Arguments 列表中。
  • 接下来,点击会将您转到此目的地的相应操作。在 Attributes 面板中,您现在应该会在 Argument Default Values 部分中看到新添加的参数。
  • 您还可以看到该参数已添加到 XML 中。点击 Text 标签页以切换到 XML 视图,就会发现您的参数已添加到接收该参数的目的地。相关示例如下所示:
 <fragment android:id="@+id/myFragment" >
     <argument
         android:name="myArg"
         app:argType="integer"
         android:defaultValue="0" />
 </fragment>

使用 Bundle 对象在目的地之间传递参数:

		// 传递
	    Bundle bundle = new Bundle();
        bundle.putString("name", "ljh");
        Navigation.findNavController(view1).navigate(R.id.action_homeFragment_to_detailFragment, bundle);
        // 接收
	    String name = getArguments().getString("name");

在目的地之间添加动画过渡效果

Navigation 组件还包含几个默认动画,以帮助您快速入门。如需向操作添加动画,请执行以下操作:

1.在 Navigation Editor 中,点击应发生动画的操作。

2.在 Attributes 面板的 Animations 部分中,点击要添加的动画旁边的下拉箭头。您可以从以下类型中进行选择:

  • 进入目的地
  • 退出目的地
  • 通过弹出操作进入目的地,弹出操作是指在导航时从返回堆栈上弹出其他目的地的操作。
  • 通过弹出操作退出目的地

3.从显示的项目动画列表中选择动画。
Android - Navigation组件_第1张图片
添加动画后,点击 Text 标签页,以切换到 XML 文本视图。动画的 XML 现在显示在相应的 元素中。

<fragment
        android:id="@+id/homeFragment"
        android:name="com.example.navigation.HomeFragment"
        android:label="Home"
        tools:layout="@layout/fragment_home">
        <action
            android:id="@+id/action_homeFragment_to_detailFragment"
            app:destination="@id/detailFragment"
            // 入场动画,针对目的地
            app:enterAnim="@anim/slide_from_left"
            // 退场动画,针对起始地
            app:exitAnim="@anim/slide_to_right">
        </action>
    </fragment>

动画的使用请参考:动画使用

你可能感兴趣的:(Android,Jetpack,android,android,studio,kotlin)