Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix back navigation issue from a secondary fragment to the map fragment #94

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

serso
Copy link

@serso serso commented Apr 16, 2024

Reproduction steps:

  1. Open the app.
  2. Open some secondary screen, for example, Area/Problems.
  3. Click on a problem.
  4. Press back.

Expected: Area/Problems screen is displayed
Actual: the app is closed

This change allows us creating a new instance
of MapFragment even when MainActivity is resumed.

Prior to this change creating another instance of MapFragment
caused a crash from Activity#registerForActivityResult:

  java.lang.IllegalStateException:
  LifecycleOwner com.boolder.boolder.view.main.MainActivity@8aabcce
  is attempting to register while current state is RESUMED.
  LifecycleOwners must call register before they are STARTED.
This change fixes an annoying user experience issue - after opening
MapFragment from a secondary screen it was not possible to get back
to that secondary screen by pressing back button.

The reason for this was that the back stack was popped up to the
MapFragment destination which was assumed to be at the bottom of
the stack.

This commit changes this behavior and navigates to a new instance
of MapFragment preserving the back stack - clicking on the back
button from the new MapFragment would navigate the user back
to the previous secondary screen.

One consequence of this change is that now it's possible to
get multiple instances of MapFragment on the back stack.
While testing I couldn't find any issue with that and assume
that it's not an issue.
@nmondollot
Copy link
Member

Hello Sergey,
Thank you for your contribution!
@wang-li will have a look at it when he's back from vacation (probably next week)
Cheers

Prior to this change pressing the back button on the
topo bottom sheet would close the app (or navigate back
in the back stack).
This was a bit annoying as the standard UX behavior
on Android should be closing the bottom sheet on back press
click.

Fix that by implementing a custom OnBackPressedCallback
which is enabled while a topo is opened.

I couldn't find a way of unselecting the problem in the
view model and instead exposed the existing
BoulderMap#unselectProblem method. I also added notifyListener
parameter to it to automatically trigger the listener (if any).
IMO it would be better to flip the default flag and set it
to `true` and only use `false` where justified (I suppose
in some cases we don't want to run bottom sheet toggle animations
too often when, for example, selecting a new topo).
@wang-li
Copy link
Collaborator

wang-li commented Apr 21, 2024

Hi @serso! 👋

First of all, thank you for your interest in the Boolder project!

Can you provide two screen recordings that showcase the difference between the initial and the fixed behavior?
Also, in the reproduction steps, it is mentioned "Open some secondary screen, for example, Area/Problems", but it seems that the PR diff is more about having the first back button press closing the topo bottom sheet than a secondary screen. Am I correct?

@serso
Copy link
Author

serso commented Apr 23, 2024

Can you provide two screen recordings that showcase the difference between the initial and the fixed behavior?

Will do when I have time.

Also, in the reproduction steps, it is mentioned "Open some secondary screen, for example, Area/Problems", but it seems that the PR diff is more about having the first back button press closing the topo bottom sheet than a secondary screen. Am I correct?

The second commit fixes the issue described in the PR. The third commit fixes another back press issue - when opening a topo from the map, pressing back doesn't close the topo but exits the app which is equally annoying to the original issue.

@wang-li
Copy link
Collaborator

wang-li commented Apr 23, 2024

@serso I just found out that some explanation was added in each commit, but I think you misunderstood the navigation of the app. The map fragment is not meant to be instantiated multiple times, as it is one of the start destinations that are accessible from the bottom navigation bar.
Then, the detail fragments can be accessed from the map, discovery or tick list fragments, building their own back stacks. The navigation to the map is considered a terminal action in terms of navigation, and any of these back stacks will be cleared, as if the app was just opened (but displaying the relevant problem or area).

Nevertheless, the fix on the back press with the topo bottom sheet being displayed is still relevant 👍

@serso
Copy link
Author

serso commented Apr 24, 2024

Here's the old and new new behavior on back press when a topo is opened from the map:

Screen_recording_20240424_092747.mp4
Screen_recording_20240424_092747.mp4

Here's the old and new new behavior on back press when a topo is opened from a secondary screen:

Screen_recording_20240424_092836.mp4
Screen_recording_20240424_092511.mp4

As you see from the videos above it was hard to quickly get back to the problems screen from the map once a problem was opened. You basically had to open the problems screen again.
The use case here is that when you arrive at some area, you might want to go from the popular problems/your projects and quickly navigate back to check another problem from the list. Not to mention that if you have misclicked, you want to recover quickly by pressing back which closed the app previously.

@serso
Copy link
Author

serso commented Apr 24, 2024

but I think you misunderstood the navigation of the app. The map fragment is not meant to be instantiated multiple times, as it is one of the start destinations that are accessible from the bottom navigation bar.

What exactly prevents the map fragment to be instantiated multiple times?

This requirement makes it impossible to navigate
Map -> Area -> Problems -> Topo (Map) -> Back to Problems -> Another Topo (Map)
or
Map -> Projects -> Topo (Map) -> Back to Projects -> Another Topo (Map)
as the map fragment is a terminal destination.

If you don't want this navigation flow then the PR can be closed but, again, I find this behavior very annoying - it happened to me many times that the app closed while I tried to go back to the previous screen. A group of people I climbed with also mentioned this usability issue.

@wang-li
Copy link
Collaborator

wang-li commented Apr 29, 2024

What exactly prevents the map fragment to be instantiated multiple times?

The back stack should not be allowed to grow indefinitely, as it can have an impact on memory, and we also want to be able to run as smooth as possible on entry level devices.

The navigation pattern that is proposed in this PR does not match the UX that we established in the app, but this is definitely an interesting point for a future redesign of the UX. We are actually curious about what motivates the need of having the list of problems right next to the map, and how this translates in physical usage in the forest.

Anyway, we would like to thank you for your proposition, as any feedback is valuable for us!

@serso
Copy link
Author

serso commented Apr 30, 2024

The back stack should not be allowed to grow indefinitely, as it can have an impact on memory

Why is that?
I don't think adding fragments to the back stack negatively affects the app performance, at least when using FragmentTransaction.replace which Android navigation library uses under the hood.
As soon as a fragment added to the back stack goes off screen, its view is destroyed and resources - freed.

I added a log statement in MapFragment on the main branch to verify that and got this printed in the logcat after opening the map screen and then navigating to an area overview screen:

MapFragment#onCreate
MapFragment#onCreateView
MapFragment#onStart
MapFragment#onResume
MapFragment#onPause
MapFragment#onStop
MapFragment#onDestroyView

As you see, as soon as AreaOverviewFragment was opened, MapFragment's view got destroyed, meaning that there are no extra resources held by non-visible MapFragment on the back stack.

We are actually curious about what motivates the need of having the list of problems right next to the map, and how this translates in physical usage in the forest.

The way I used it was: I compiled a list of boulders I wanted to try at home, added them to projects and then went through the projects list in the forest.
Sometimes I just opened a list of popular problems on the problems screen and went through it. But it was painful, as after opening one topo it was not possible to go back and open another topo from the list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants