Reputation: 62
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.
Upvotes: 0
Views: 658
Reputation: 3263
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 add
ing 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:
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.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.
Upvotes: 1
Reputation: 1
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;
}
Upvotes: 0