0

I am working on fragments, but there is a problem when i switch from one fragment to other view overlap eachother.

I am using following code to switch fragments.

getSupportFragmentManager() .beginTransaction() .add(R.id.mainContainer, new SecondsFragment()) .addToBackStack(null) .commit(); 

I know that using add() will only add newer fragment over the previous one. I dont want to use replace because it reloads everything when i return to that fragment using onBackPress() e-g i have REST API calls in first fragment when i open second fragment using replace() function and return to first fragment it will again call that REST API, which is not good for UX.

If i use add() to load second fragment, the view of second fragment overlaps view of first fragment, and returning to first fragment not call that REST API (my desired behaviour).

I also know that by setting background of fragments xml parent view, this issue can be resolved but then it will also cause accidental clicks on first fragments views again bad for UX, i also read in SO by setting parent view clickable to true will resolve this issue too, but as other developers said it is just a hack not a proper solution.

I am expecting users like commonsware to address this question.

Any suggestions/comments are highly welcome.

Thanks in Advance.

8
  • 1
    I am expecting users like commonsware to address this question and why Commented Dec 7, 2017 at 10:32
  • use fragment.newInstance() Commented Dec 7, 2017 at 10:32
  • Are your fragments in an activity or in another fragment? Commented Dec 7, 2017 at 10:33
  • @Nilu commonsware is a big thing about android, they know android inside and out. Commented Dec 7, 2017 at 10:37
  • @elmorabea my fragments are in Activity Commented Dec 7, 2017 at 10:38

2 Answers 2

1

I'll try to take a shot at that, I think you are miss-understanding the semantics of the add() in a FragmentTransaction, is that you are adding another fragment, this should not have any effect on fragment that are already added. Which means that both your fragments are active or RESUMED in terms of FragmentManager states.

The fact that your second fragment is as big as your first one, and is positioned on top of it, is merely an implementation detail only you are concerned with, as far as FragmentManager goes, both your fragments are RESUMED, active and intractable by the user.

Basically, if add() should somehow suspend the currently added fragment before adding the new one, why would we need another API for replace()

You are fixing one issue (not wanting to re-do a network request) by abusing a different feature (adding fragments).

If you want for only one fragment to be active at a time, then you need to remove the old fragment first, either by explicitly calling remove() or by having it done for you with a call to replace().

And to avoid the issue of doing a network request again, you can either:

  • Add your first fragment to the back stack add, and using pop() to go back to the same instance of your fragment, this will require some logic in your fragment to check if a certain state is not null, then no need to do the network call.
  • Saving the instance of your fragment manually in the containing Fragment/Activity, and then when you are adding your old fragment again, you add the existing instance, instead of creating a brand new one.

However, if your intent is indeed to have both of them added, but you want to restrict the user's ability to see/interact with the first fragment, you an use show(), hide() to do that.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for elaborating, and i also understand that basically replace() will first remove() the fragment and then will add() new fragment. I definitely never knew about hide(), show(), sure going to dig these two methods.
0

You can instance first fragment and set it as active fragment. When you select second fragment, hide active fragment (fragment 1), and set second fragment as active.

Ex.

 fragment1 = Fragment1.newInstance(); active = fragment1; getFragmentManager() .beginTransaction() .add(R.id.fragment_container, fragment1, "1") .commit(); 

When you select your second fragment, you can do something like this:

 if (isFirstTimeLoading) { fragment2 = Fragment2.newInstance(); getFragmentManager() .beginTransaction() .add(R.id.fragment_container, fragment2) .hide(active) .commit(); active = fragment2; isFirstTimeLoading = false; } else { getFragmentManager() .beginTransaction() .hide(active) .show(fragment2) .commit(); active = fragment2; } 

3 Comments

Don't t you think this is static approach, i only gave example of two fragments, i have more than 30 fragments i cannot do this for every frament.
I use this approach when have four or less fragments... but why would you have 30 fragments in backstack, will it causes a memory leak?
there is memory leak yet!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.