Reputation: 2135
Is there a way to clear navArgs after using them? I have fragment A that opens fragment B with navArgs, then I navigate to fragment C and the user presses back, so fragment B is opened with the same navArgs and I don't want that.
Is there a way to navigate back to fragment B without the navArgs?
Thanks.
Upvotes: 15
Views: 6325
Reputation: 1
if you only want to remove one Argument from navArgs you could use
requireArguments().remove("yourArgument")
Remember to use Android:defaultValue inside declaration on your navigation Xml, if you don't do it your app will crash because it won't find the argument previously declared
Upvotes: 0
Reputation: 5682
Calling arguments?.clear()
is not sufficient. Reason for that is that the navArgs()
delegate holds all arguments in a local cached variable. Moreover, this variabel is private:
(taken from NavArgsLazy.kt)
private var cached: Args? = null
override val value: Args
get() {
var args = cached
if (args == null) {
...
args = method.invoke(null, arguments) as Args
cached = args
}
return args
}
I also find this approach pretty stupid. My use-case is a deeplink that navigates the user to a specific menu item of the main screen in my app. Whenever the user comes back to this main screen (no matter wherefrom), the cached arguments are re-used and the user is forced to the deeplinked menu item again.
Since the cached
field is private and I don't want to use reflections on this, the only way I see here is to not use navArgs
in this case and get the arguments manually the old-school way. By doing so, we can then null them after they were used once:
val navArg = arguments?.get("yourArgument")
if (navArg != null) {
soSomethingOnce(navArg)
arguments?.clear()
}
Upvotes: 8
Reputation: 143
The answer suggested by Juanjo absolutely does work.
The only caveat is that you can't use the navArgs
property delegate to get at them since it's wrapped Lazy
.
Instead you just go through the underlying arguments
bundle.
For example, in FragmentB
// don't need to pull in the navArgs anymore
// val args: FragmentBArgs by navArgs()
override fun onResume() {
when (FragmentBArgs.fromBundle(arguments!!).myArg) {
"Something" -> doSomething()
}
// clear it after using it
arguments!!.clear()
}
// now they are cleared when I go back to this fragment
Upvotes: 12
Reputation: 789
I think you could to remove the arguments when your fragment B will be destroyed
You could use the method getArguments().clear();
in onDestroyView() or whenever you want to clear the arguments in your fragment.
Upvotes: 1