Android 导航架构组件:如何将捆绑包数据传递给 startEstination

我有一个活动,它有一个.活动在其意图中接收某些值。我想将此数据传递到第一个片段,即导航图。我找不到有关此内容的任何文档。NavHostFragmentstartDestination

我已经在SO上经历了这个问题,但我似乎找不到.addDefaultArgumentsnavController.getGraph()

是否可以将捆绑包传递给 ?startDestination


答案 1

回答我自己的问题,因为我在更新的导航文档中找到了正确的方法。

在撰写此答案时,我正在使用Navigation 2.2.0-alpha01

如果要将一些数据作为主机活动的参数直接传递到起始目标,则需要在主机活动的 onCreate() 方法中手动设置主机的导航图,如下所示:

Get you navController:

val navController by lazy { findNavController(R.id.<your_nav_host_id>) }

然后在主机活动的onCreate()

val bundle = Bundle()
bundle.putString("some_argument", "some_value")
navController.setGraph(R.navigation.<you_nav_graph_xml>, bundle)

或者,如果您想将整个意图附加功能传递到开始目的地:

navController.setGraph(R.navigation.<you_nav_graph_xml>, intent.extras)

因为将返回一个intent.extrasBundle

使用 setGraph() 方法设置 navGraph 时,应避免在 NavHostFragment 定义中设置 app:NavGraph 属性,因为这样做会导致膨胀和设置导航图两次。

在阅读 startDestination 片段中的这些参数时:

如果您使用的是Safe Args插件(非常推荐),那么在您的片段中:

private val args by navArgs<DummyFragmentArgs>()

Safe Args 插件会通过将 Args 附加到您的片段名称来生成一个 Args 类。例如,如果调用片段,则 Safe Args 将生成一个名为DummyFragmentDummyFragmentArgs

其中 是在 Android KTX 中定义的扩展函数navArgs<>

如果你没有使用 Android KTX,你可以得到 args 对象,如下所示:

val args = DummyFragmentArgs.fromBundle(arguments!!)

获取参数对象后,只需获取参数即可:

args.someArgument

请注意我们如何作为参数传递,并且我们正在将其解读为使用Safe Args"some_argument"someArgument

如果您没有使用Safe Args(没有理由不使用它),则可以像这样访问您的参数:

arguments?.getString("some_argument")

所有这些都记录在此处的迁移到导航组件文档中:https://developer.android.com/guide/navigation/navigation-migrate#pass_activity_destination_args_to_a_start_destination_fragment


答案 2

经过一些研究,我找到了解决方案。它适用于最新的导航库版本。请参考以下代码:

  1. 将其添加到活动布局中。注意:我们不会在 xml 文件中设置 app:navGraph 参数。我们将动态设置它。

    <fragment
        android:id="@+id/fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        app:defaultNavHost="true" />
    
  2. 在活动 java 文件中,编写以下代码并进行相应的更改。使用 NavArgument 传递参数值,并将参数添加到自定义导航图,然后设置图形。

    public class YourActivity extends AppCompatActivity {
         private NavArgument nameArg, mailArg;
    
         @Override
         protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.profile);
            nameArg = new NavArgument.Builder().setDefaultValue("your name").build();
            mailArg = new NavArgument.Builder().setDefaultValue("your email id").build();
            NavController navController = Navigation.findNavController(this, R.id.fragment);
            NavInflater navInflater = navController.getNavInflater();
            NavGraph navGraph = navInflater.inflate(R.navigation.nav_profile_graph);
            navGraph.addArgument("your name key", nameArg);
            navGraph.addArgument("your mail key", mailArg);
            navController.setGraph(navGraph);
        }
    }
    
  3. 编写下面的导航图,并将相同的参数键添加到起始片段中。

    <?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/profile_basic">
    
       <fragment
          android:id="@+id/profile_basic"
          android:name="com.yourpackage.ProfileBasicFragment"
          android:label="Profile Basic"
          tools:layout="@layout/fragment_profile_basic">
    
          <argument android:name="your name key"
              app:argType="string"/>
    
          <argument android:name="your mail key"
              app:argType="string"/>
    
       </fragment>
    </navigation>
    
  4. 在你的片段中,只需使用 getArguments() 函数获取值。

    String name = getArguments().getString("your name key");
    String mail = getArguments().getString("your mail key");
    

推荐