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 WorkspaceFragmentIan 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 PMCreateWorkspaceFragmentTudor 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