Navigation学习【一】——简单使用

Navigation的简单使用Demo

导航概述

导航组件由三个关键部分组成,它们相互协调工作。他们是:

  • 导航图(新XML资源)-这是一种资源,它在一个集中位置包含所有与导航有关的信息。这包括应用程序中的所有位置,称为destinations,以及用户可以通过您的应用程序选择的可能路径。
  • NavHostFragment(布局XML视图)-这是添加到布局中的特殊小部件。它从您的导航图显示不同的目的地。
  • NavController(Kotlin / Java对象)-这是一个跟踪导航图中当前位置的对象。NavHostFragment当您浏览导航图时,它会在中协调交换目标内容。

导航时,将使用NavController对象,在“导航图”中告诉它您想去的地方或要走的路径。然后,NavController它将在NavHostFragment中显示适当的目的地。

注意:如果要使用导航和 Android Studio,则必须使用 Android Studio 3.3 或更高版本。

导入

获取最新版本。

appbuild.gradle 中添加依赖:

dependencies {
  def nav_version = "2.1.0"

  // Java
  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"

}

使用

  1. 创建导航图nav_graph.xml

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

nav_graph.png
  1. Activity 添加 NavHost




    
    

下面对三个比较重要的属性做一下解释:

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

    res/navigation/nav_graph.xml中通过startDestination设置起始fragment,当然这里也可以通过design模式通过点击相关图标去设置,这里不好演示就通过展示代码来实现。

    
    
    
    
        
    
       
    
    

ok,到了这里项目就可以正常运行了。

简单跳转

  1. res/navigation/nav_graph.xml中设置跳转Action

    
    
    
    
        
            
            
            
        
    
        
    
    
  2. 使用Navigation实现跳转逻辑

    核心代码:Navigation.findNavController(view).navigate(R.id.viewTransactionsAction);

    //FirstFragment.java
    public class FirstFragment extends Fragment {
    
        private View mView;
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            mView = inflater.inflate(R.layout.fragment_first, container, false);
            return mView;
        }
    
        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
    
            Button jumpBtn = mView.findViewById(R.id.jump_btn);
            jumpBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    NavController navController = Navigation.findNavController(mView);
                    //action_firstFragment_to_secondFragment 之前设置的action id
                    navController.navigate(R.id.action_firstFragment_to_secondFragment);
                }
            });
    
            //对于点击事件还可以这么做
            //jumpBtn.setOnClickListener(Navigation.createNavigateOnClickListener(R.id.action_firstFragment_to_secondFragment));
        }
    }
    

传递参数

  1. res/navigation/nav_graph.xml设置所需参数

    
    
    
    
        ...
    
        
    
            
            
        
    
    

Navigation 库支持以下参数类型:

类型 app:argType 语法 是否支持默认值? 是否支持 null 值?
整数 app:argType="integer"
浮点数 app:argType="float"
长整数 app:argType="long" 是 - 默认值必须始终以“L”后缀结尾(例如“123L”)。
布尔值 app:argType="boolean" 是 -“true”或“false”
字符串 app:argType="string"
资源引用 app:argType="reference" 是 - 默认值必须为“@resourceType/resourceName”格式(例如,“@style/myCustomStyle”)或“0”
自定义 Parcelable app:argType="",其中 Parcelable 的完全限定类名称 支持默认值“@null”。不支持其他默认值。
自定义 Serializable app:argType="",其中 Serializable 的完全限定类名称 支持默认值“@null”。不支持其他默认值。
自定义 Enum app:argType="",其中 是 Enum 的完全限定名称 是 - 默认值必须与非限定名称匹配(例如,“SUCCESS”匹配 MyEnum.SUCCESS)。
  1. 启动并传参

    • 不使用Safe Args

      //发送方通过bundle存储数据并通过navigate方法传递
      Button jumpBtn = mView.findViewById(R.id.jump_btn);
      jumpBtn.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              NavController navController = Navigation.findNavController(mView);
              //action_firstFragment_to_secondFragment 之前设置的action id
              Bundle bundle = new Bundle();
              bundle.putString("content","from firstFragment");
              navController.navigate(R.id.action_firstFragment_to_secondFragment,bundle);
          }
      });
      
      //接收方:
      TextView textView = mView.findViewById(R.id.second_tv);
      textView.setText(getArguments().getString("content"));
      
  • 使用 Safe Args

    1. 请在顶级 build.gradle 文件中包含以下 classpath

       buildscript {
           repositories {
               google()
           }
           dependencies {
               def nav_version = "2.1.0"
               classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
           }
       }
      
    2. 将以下行添加到应用或模块build.gradle 文件中:

      #java
      apply plugin: "androidx.navigation.safeargs"
      
      #kotlin
      apply plugin: "androidx.navigation.safeargs.kotlin"
      
    3. 使用:

      //发送方  通过自动生成的xxDirections.action去构建
      FirstFragmentDirections.ToSecond toSecond = FirstFragmentDirections.toSecond("from FirstFragment")
                              /*.setContent("sss")*/;  //如果参数可为空可通过set方法添加
      Navigation.findNavController(mView).navigate(toSecond);
      
      //接收方
      TextView textView = mView.findViewById(R.id.second_tv);
      String content = SecondFragmentArgs.fromBundle(getArguments()).getContent();
      textView.setText(content);
      

混淆

  • 通过 @keep 注解:

    @Keep public class ParcelableArg implements Parcelable { ... }
    
  • 使用keepnames规则

    ...
    
        -keepnames class com.path.to.your.ParcelableArg
        -keepnames class com.path.to.your.SerializableArg
        -keepnames class com.path.to.your.EnumArg
    
        ...
    

补充

  • Activity中获取NavController
//activity中获取NavController  第二个参数为navigation的id
NavController navController = Navigation.findNavController(this, R.id.nav_graph);
navController.handleDeepLink(new Intent());

参考文章

  • Navigation
  • 导航原则
  • Navigation使用入门
  • 导航 Codelab
  • Android Jetpack - 使用 Navigation 管理页面跳转

你可能感兴趣的:(Navigation学习【一】——简单使用)