由于使用了Navigation,导致Fragment的创建行为完全交给了系统。也就是说,以前的那种通过#Fragment.newInstance(Args...)方式传递参数的方式就被切断了,没有办法快乐的在fragment之间传参了~~。但是不要担心,google爸爸早就帮我们想好了方式,下面我们来一条一条的看看吧:
1.通过NavController.navigate(int, bundle)方法传参。
这个是Navigation中提供的最原始的一种参数传递的方法,我们只需要在使用这个函数导航的时候,将原先需要在newInstance()中传递的bundle对象放在改方法的第二个参数中。系统就会帮我们将bundle传递到目标fragment/activity的argument/Intent中,只需要和之前一样,在跳转到的fragment/activity中调用getArgument()/getIntent(),就可以获得我们传递的Bundle对象。我们来看看源码,探索下系统到底怎么是帮我们实现的吧!(没有兴趣的同学可以直接跳过)
public final void navigate(@IdRes int resId, @Nullable Bundle args) { navigate(resId, args, null); }
可以看到在这个方法体中系统只是简单的帮我们做了转调。我们继续:
NavController.java:
public void navigate(@IdRes int resId, @Nullable Bundle args, @Nullable NavOptions navOptions) { ... node.navigate(args, navOptions); }
NavDestination.java:
public void navigate(@Nullable Bundle args, @Nullable NavOptions navOptions) { Bundle defaultArgs = getDefaultArguments(); Bundle finalArgs = new Bundle(); finalArgs.putAll(defaultArgs); if (args != null) { finalArgs.putAll(args); } mNavigator.navigate(this, finalArgs, navOptions); }
public abstract void navigate(@NonNull D destination, @Nullable Bundle args, @Nullable NavOptions navOptions);
最后我们可以看到,它指向了到了一个抽象类(Navigator)中的抽象方法。
这个抽象方法具体有3个主要实现:
1.ActivityNavigator.navigate(...):
@Override public void navigate(@NonNull Destination destination, @Nullable Bundle args, @Nullable NavOptions navOptions) { if (destination.getIntent() == null) { throw new IllegalStateException("Destination " + destination.getId() + " does not have an Intent set."); } Intent intent = new Intent(destination.getIntent()); if (args != null) { intent.putExtras(args); String dataPattern = destination.getDataPattern(); if (!TextUtils.isEmpty(dataPattern)) { // Fill in the data pattern with the args to build a valid URI StringBuffer data = new StringBuffer(); Pattern fillInPattern = Pattern.compile("\\{(.+?)\\}"); Matcher matcher = fillInPattern.matcher(dataPattern); while (matcher.find()) { String argName = matcher.group(1); if (args.containsKey(argName)) { matcher.appendReplacement(data, ""); data.append(Uri.encode(args.getString(argName))); } else { throw new IllegalArgumentException("Could not find " + argName + " in " + args + " to fill data pattern " +