0

I know it's recommended to use Fragments instead of Activities when working with Bottom Navigation. Due to the current design, I want to avoid having to convert all the Activities

The Design: I am using a Bottom Navigation bar like shownenter image description here

Each tab is an Activity. When you tap on any of the tabs, it launches the activity, startActivity(new Intent(getApplication(), TabActivityName.class));. The problem is that when you switch between these tabs, the state of the Activity is lost.

For example:

  1. Click on the Music tab (Shows a list of artists)
  2. Click on an artist in the Music tab to show the Discography fragment.
  3. Switch to the Video tab
  4. Switch back to the Music tab. (I want the Artist's discographyFragment to still be showing, but it is back at the main List of Artists fragment)

Things I've tried:

  1. Changing each of the tab Activities to android:launchMode="singleTask" and android:alwaysRetainTaskState="true" This only preserves data if you are switching to tabs that were started before the current activity.
  2. Changing each of the tab Activities to android:launchMode="singleInstance" and android:alwaysRetainTaskState="true" But this creates an undesired effect of creating multiple application tabs.

Any other ideas on how to maintain the state of the Activity and which Fragment is loaded when switching tabs?

Alan
  • 9,331
  • 14
  • 52
  • 97

2 Answers2

1

You could use FragmentStatePagerAdapter in the Activities. However, you should update to fragments, they are designed to handle your situation. The migration is not that bad, most of the logic can simply be copied over.

RestingRobot
  • 2,938
  • 1
  • 23
  • 36
  • I am not sure if you have used the Instagram app. It seems to be able to maintain the navigation stack and state of each tab. Does that mean that the entire application is only ONE Activity? – Alan May 26 '17 at 16:12
  • While I don't know exactly what they are doing, the same functionality can be achieved by maintaining the state of fragments within an activity. https://developer.android.com/guide/components/fragments.html – RestingRobot May 26 '17 at 17:36
  • 1
    As a caveat it is not uncommon to have one activity managing a large portion of modern applications. Instagram may very well only have one main activity. – RestingRobot May 26 '17 at 17:37
  • ugh. that seems very poorly designed compared how iOS designs layouts. The singular activity would end up having a whole lot of logic making it less readable and modular. – Alan May 30 '17 at 19:10
  • Thats the whole point of fragments, your logic for each "module" should be in the fragments and only communicate with the activity for basic functions. Think of a fragment as a ViewController, and an activity as a NavigationViewController, (overly simplified, I know, but the general idea). – RestingRobot May 30 '17 at 19:12
  • Oh, I agree that's the whole point of fragments. I have always like the Activities to handle the web calls and other higher level logic and let the Fragments handle the "View". For instance from my question above, it seems to make sense that each Tab should be an Activity because they are all separate activities/functions... The tab's activity would then handle all web service calls and communication between fragments within that tab... To think that there is now One Activity to control every tab seems extremely messy. – Alan May 30 '17 at 19:20
  • 1
    It sounds like you would really benefit from an MVP like structure, here is an amazing example from Google, https://github.com/googlesamples/android-architecture/tree/todo-mvp – RestingRobot May 30 '17 at 19:44
  • hmm, very interesting. Looks like the `Presenter` acts as the middleman between the Fragment and Activity. Seems to me like all the duties normally given to the Activity is now offloaded to the Presenter for code readability/organization purposes. Doesn't seem to show who would be handling fragment interactions. Would the presenter be handling communication between fragments? It seems to make the Activity useless... basically an initializer. – Alan May 30 '17 at 20:01
  • from the sample code they provided, looks like an actual class e.g. StatisticsActivity that initializes the StatisticsFragment & StatisticsPresenter which both implement a StatisticsContract – Alan May 30 '17 at 20:10
  • Yes you are right, but the activity is like the base for the presenter and fragment. They use the same Contract, an interface. In the context of M(odel) V(iew) P(resenter), the activity would fall under the Presenter section and the Fragments would be in the View section. – RestingRobot May 30 '17 at 20:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/145494/discussion-between-jlange-and-alan). – RestingRobot May 30 '17 at 20:14
0

My current app has the same kind of design. Bottom menu has different icons that launches activities and each activity has fragments in it.

I solved the problem by using FLAG_ACTIVITY_REORDER_TO_FRONT before launching the bottom menu activities.

    case R.id.ic_house:
                        Intent intent1=new Intent(context, HomeActivity.class);
                        intent1.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                        context.startActivity(intent1);
                        break;
    case R.id.ic_more:
                        Intent intent2=new Intent(context, MoreActivity.class);
                        intent2.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                        context.startActivity(intent5);
                        break;

This question is 3 years old but maybe someone else finds this solution helpful.

otnemem
  • 13
  • 5
  • Use Navigation Architecture with Fragment. This is the solution for that https://github.com/android/architecture-components-samples/tree/master/NavigationAdvancedSample – Sharad May 19 '20 at 01:51