Tudor Luca
01/11/2021, 9:47 PMWorkspacesListFragment WorkspaceFragment ThreadFragment
R.id.workspacesListFr R.id.workspaceFr R.id.threadFr
+--------------------+ +-----------------+ +----------------+
| | | | | |
| List: | arg: workspaceId | List: | arg: threadId | |
| * kotlinlang +--------------------> * androidx +-----------------> |
start dest | * workflow-kotlin | | * compose | | |
+-----------> * etc... | | * etc... | | |
| | | | | |
| | | | | |
| | | | | |
+------+-------------+ +-----------------+ +----------------+
|
|
|
|
| CreateWorkspaceFragment
|
| +--------------------------+
| | |
| | besides a new workspace, |
| | optionally could create |
+--------> a new thread as well |
| |
| has workspaceId |
| has threadId? |
| |
| |
| |
+--------------------------+
When a new workspace is created I'd like to navigate to it when the operation is successful. I've come up with 2 ideas:
Option 1: use the navigation controller available inside CreateWorkspaceFragment and navigate directly from there:
CreateWorkspaceFragment {
...
fun onComplete(workspaceId: String, threadId: String?) {
val navController = findNavController()
// 1. Go back to WorkspacesListFragment
// fragment will trigger an async api call to fetch and then display the list
navController.popBackStack()
// 2. Go to WorkspaceFragment
// fragment will trigger an async api call to fetch and then display the workspace
navController.navigate(
WorkspacesListFragmentDirections.actionToWorkspace(workspaceId)
)
// 3. Go to ThreadFragment if user created a thread
// fragment will trigger an async api call to fetch and then display the thread
if (threadId.isNullOrEmpty().not()){
navController.navigate(
WorkspaceFragmentDirections.actionToThread(threadId!!)
)
}
}
}
Option 2:
• return workspaceId & threadId as a result to the previous WorkspacesListFragment
Destination (either FragmentResult API or navController.previousBackStackEntry?.savedStateHandle )
• from WorkspacesListFragment
I can navigate to WorkspaceFragment
and pass along workspaceId & threadId
• inside WorkspaceFragment.onCreate
I can check the args and if there's a threadId I'll trigger navigation from there to ThreadFragment
(but I'll have to WorkspaceFragment.arguments = null
, otherwise when coming back it'll navigate to ThreadFragment
again, indefinitely)
Essentially, Option 1 come down to handling my navigation logic in-place and Option 2 would spread it across each destination. FragmentNavigator does Fragment transactions asynchronously, Option 1 acts like navigation is a synchronous operation and it doesn't seem right to me... but Option 2 is a lot more code, so...
Suggestions? (anyone from the androidx.navigation team around here?)Ian Lake
01/11/2021, 9:51 PMnavigate()
is a synchronous operation (even if the fragment operations aren't), so just call navigate()
and popBackStack()
as you want. That's exactly how deep linking works FWIWIan Lake
01/11/2021, 9:52 PMpopUpTo
to pop your create fragment on the way to the destination instead of manually calling popBackStack()
as that will avoid a dispatch to any OnDestinationChangedListener
and make it a single atomic operationTudor Luca
01/11/2021, 9:58 PMIan Lake
01/11/2021, 10:02 PMpopUpTo
that the docs don't cover? https://developer.android.com/guide/navigation/navigation-navigate#popIan Lake
01/11/2021, 10:04 PMWorkspacesListFragment
-> CreateWorkspaceFragment
and want to be at a back stack of WorkspacesListFragment
-> WorkspaceFragment
, then you want to popUpTo
CreateWorkspaceFragment
with popUpToInclusive="true"
and a destination of WorkspaceFragment
Ian Lake
01/11/2021, 10:07 PMpopUpTo
to pop multiple destinations before you navigate to your new destination, you can only add one destination to the back stack at a time, so if you wanted to go all the way to ThreadFragment
, you'd have to do a separate navigate()
afterward with WorkspaceFragmentDirections.actionToThread()
as you are doing, yes.Tudor Luca
01/11/2021, 10:11 PMIan Lake
01/11/2021, 10:13 PMthat will avoid a dispatch to anyand make it a single atomic operationOnDestinationChangedListener
Ian Lake
01/11/2021, 10:16 PMCreateWorkspaceFragment
Tudor Luca
01/11/2021, 10:23 PM.navigate()
calls if I want to reach Thread from Create, right?
// 1. Go back to WorkspacesListFragment
navController.navigate(
CreateWorkspaceFragmentDirections.actionBackToWorkspaceList()
)
// 2. Go to WorkspaceFragment
navController.navigate(
WorkspacesListFragmentDirections.actionToWorkspace(workspaceId)
)
// 3. Go to ThreadFragment
navController.navigate(
WorkspaceFragmentDirections.actionToThread(threadId!!)
)
Ian Lake
01/11/2021, 10:28 PMpopUpTo
as part of the move to the WorkspaceFragment:
// 1. Go to WorkspaceFragment, popping create on the way out by adding a popUpTo to this action
navController.navigate(
CreateWorkspaceFragmentDirections.actionToWorkspace(workspaceId)
)
// 2. Go to ThreadFragment
navController.navigate(
WorkspaceFragmentDirections.actionToThread(threadId!!)
)
Tudor Luca
01/11/2021, 10:40 PMTudor Luca
01/11/2021, 11:18 PM