jb3rndt / PersistentBottomNavBarV2

A highly customizable persistent bottom navigation bar for Flutter
https://pub.dev/packages/persistent_bottom_nav_bar_v2
BSD 3-Clause "New" or "Revised" License
47 stars 48 forks source link

Add unique history for controller #138

Closed danut007ro closed 2 months ago

danut007ro commented 3 months ago

Allows the PersistentTabController history to be unique, meaning that each tab will have only one entry in the history. Initial tab will always keep the first index.

When 3 tabs are shown (0, 1, 2) switch tabs in the following order (1, 2, 1, 0, 2). Going back from tab 2 will go to 1 then 0 and exit.

danut007ro commented 3 months ago

Hello @jb3rndt . Is there anything I can do to move this forward? Thanks a lot.

jb3rndt commented 3 months ago

Hi, thank you for contributing. I'm not entirely sure yet if this is desirable, but I have another question for now:

When 3 tabs are shown (0, 1, 2) switch tabs in the following order (1, 2, 1, 0, 2). Going back from tab 2 will go to 1 then 0 and exit.

Why should it return in the order 2, 1, 0 instead of 2, 0, 1 (which were the recently selected unique tabs)?

danut007ro commented 3 months ago

My idea was to have the first tab (that is shown when starting app) to be displayed last, before leaving the application. This can be configured with an option if that is desirable.

Right now, for me it seems not very user friendly to go back 10 times (if I navigated 10 times on the same 2 or 3 tabs) in order to be able to leave the app.

I can add a flag to keep the "real" history if that's desirable. Let me know what you think.

Thank you.

On Fri, Apr 5, 2024, 18:51 Jannis Berndt @.***> wrote:

Hi, thank you for contributing. I'm not entirely sure yet if this is desirable, but I have another question for now:

When 3 tabs are shown (0, 1, 2) switch tabs in the following order (1, 2, 1, 0, 2). Going back from tab 2 will go to 1 then 0 and exit.

Why should it return in the order 2, 1, 0 instead of 2, 0, 1 (which were the recently selected unique tabs)?

— Reply to this email directly, view it on GitHub https://github.com/jb3rndt/PersistentBottomNavBarV2/pull/138#issuecomment-2040145572, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAIIN7U4R5LUHYHYWOHRCR3Y33CAJAVCNFSM6AAAAABFUZRMS6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANBQGE2DKNJXGI . You are receiving this because you authored the thread.Message ID: @.***>

jb3rndt commented 3 months ago

Okay, yes I understand your point. I agree that switching 10 times before exiting is not desirable.

Lets imagine the following scenario from your initial post (3 tabs total):

  1. I start at tab 0 (initial index)
  2. switch to tab 1
  3. switch to tab 0
  4. switch to tab 2

From what I understand, the unique history would do the following:

  1. on android back button press: switch to tab 1
  2. on android back button press: switch to tab 0
  3. on android back button press: close app

In this case, the user switched from 0 to 2 but when pressing the back button the app would take him to 1. In my opinion, this is confusing for the user.

So I was thinking about some other options:

Option 1

(this option will always exit after showing the initial tab) Every time the user switches to the initial tab, all the history before that will be erased and everything that happens afterwards is transformed to be unique while maintaining the correct order. Note: when talking about maintaining the order in the unique history I would always remove the oldes entries of multiple occurences of the same tab. E.g. 0 -> 1 -> 2 -> 1 -> 0 -> 2 would result in 1 -> 0 -> 2

Example:

Full switching history (including the initial tab 0): 0 -> 2 -> 1 -> 2 -> 0 -> 2 -> 1 -> 2 This would result in the following history which would be read from the back when pressing the back button repeatedly: 0 -> 1 -> 2.

Imo this option has the downside in the following case: Full history: 0 -> 2 -> 1 -> 2 -> 1 -> 0 -> 2 Which results in this: 0 -> 2 As a user, I would probably remember being on tab 1 before tab 0, so the exit would not be expected by me.

Option 2

(this option will not always show the initial tab before exiting) The history is made unique while maintaining the correct order and just exits at the end. Effectively, this is like option one without cutting off the history at the initial tab.

Example:

Full history: 0 -> 1 -> 2 -> 0 -> 1 -> 0 -> 2 Result: 1 -> 0 -> 2

This option (and option 1 as well) have the same problem that I described in the very beginning. Additionally, this option does not show the initial tab before exiting.

Option 3

We keep the history as it is (without removing duplicates or anything) but simply limit the length of the history i.e. the amount of back presses that it takes to exit the app. I have not read any scientific research about that, but lets imagine the average user can roughly remember the last 5 tabs he visited. So we could just limit the history to 5 elements, then it always shows the initial tab end exits the app afterwards. This causes the history being exactly what the user remembers an thus does not cause any confusion while being short at the same time.

Summary

In my opinion right now, everything that alters the history causes unexpected behavior and should not be done. This is why i favor option 3 but I am very curious on your opinion. So let me know what you think :)

P.S.: Actually, it might make sense to observe how other apps handle this but it might be difficult to observe any pattern or find a majority

danut007ro commented 3 months ago

Previous version of this package handled the back button quite good I would say, by switching to first tab and then leave https://github.com/jb3rndt/PersistentBottomNavBarV2/blob/v4.2.8/lib/persistent-tab-view.widget.dart#L33

I did a little research on apps that I have installed on my phone and this happened on aliexpress and quora. Facebook seems like my implementation but there is a case where it's handled differently. I agree that there isn't a standard way of doing it.

I would go for option 3 also, with a configurable history limit, so setting limit=0 will go to first tab and then leave. Best of both worlds.

jb3rndt commented 3 months ago

Ok, thank you for testing. Sounds good 👍

danut007ro commented 3 months ago

Hello again @jb3rndt. As agreed (hopefully) I implemented a historyLength for PersistentTabController which requires a positive number and allows for multiple use cases (as per option 3 above).

When historyLength is 0, pressing back will ignore all history and just exit. When historyLength is 1, pressing back will jump to initial tab. Pressing back again will exit. When historyLength is 2, pressing back will jump to previous tab, then to initial tab, then exit. And so on...

New entries will overwrite the history, which will be kept to a size of at most historyLength elements, with initial tab on the first position. Special handling was done to not allow the second entry in history to be the same as the the first one (initial tab).

This parameter is treated like the number of back button presses required to exit.

Note: please take a look at the calcCanPop() method, as the check there was required when historyLength was 0 and a tab switch was attempted.

danut007ro commented 3 months ago

Hello @jb3rndt . This PR is ready again for review, with docs and tests included.

There was an issue when historyLength=1, switching from 1>0>1 then pressing back then I was unable to exit.

I added some more updates to PersistentTabView which fixed the test where historyLength is 1 and initial tab has subpage.

Thank you fo guiding me.

RB-93 commented 2 months ago

Meanwhile,

@jb3rndt There's an issue in current back navigation stack, where the pkg remembers the last visited tab pages.

Now, pressing Android back button, the tab deosn't switch/navigates to previously visited list of tab indexes. It just simply puts the app in background with current state of tab.

This is observed in v5.2.2 which haven't produced since 4 iteratons.

jb3rndt commented 2 months ago

@RB-93 Please make sure to set handleAndroidBackButtonPress: true. If that does not fix it, please open a new issue.

RB-93 commented 2 months ago

@RB-93 Please make sure to set handleAndroidBackButtonPress: true. If that does not fix it, please open a new issue.

Yes, that is already set to true by default.