Android Fragment - add and bring to front - android

The thing I'm trying to achieve should be quite simple but I can't manage to find the solution to my problem.
I have fragment A. When fragment A's button is clicked, fragment B is displayed:
#Override
public void onClick(View v) {
Fragment fragment = new PostMeasurementFragment();
FragmentTransaction fragmentTransaction = ((PostActivity)context).getSupportFragmentManager().beginTransaction();
fragmentTransaction.addToBackStack(null);
fragmentTransaction.add(R.id.post_container, fragment, "PostMeasurementFragment");
fragmentTransaction.commit();
}
Fragment B has a transparent background so I'd like fragment A to be visible behind fragment B. If I use .replace rather than .add, I can see only fragment B and that's make sense because fragment A was removed by the .replace method. When I use .add I can't see fragment B though and I know it's there because of .addToBackStack: I need to click the back button twice to get rid of fragment A, which makes me thing the first click is quitting fragment B which I can't see.
Given that, I believe fragment B is being added behind (or below, if you think of it as a pile) of fragment A. Is there a way to bring it to front?

Inflate Fragment B into a view in the layout of Fragment A (such as a FrameLayout) where the height that view is set to wrap_content, and the Fragment's view will fill whatever size necessary. Use add() when building the FragmentTransaction.

Related

Save Fragment View when popbackstack from Fragment B to A (like. finish in activity)

I have two fragments FRAGMENT A and FRAGMENT B. WhenI go from FRAGMENT A to FRAGMENT B I am adding FRAGMENT A in backstack using addtobackstack(null) and also using replace() method. The problem is when I call popbackstack() from FRAGMENT B --> FRAGMENT A then OnCreateView() and onViewCreated() calls again and It loads the recycler view again in FRAGMENT A. I know all the instance are not loaded again
but the problem is I do not want to load view again. Ex. in activity when i call finish previous activity remain same as we left.
NOTE : I don't want to use add() method in beginTransaction because it overlap other fragment.
Thanks
For reference:
One more importance difference between add and replace is: replace
removes the existing fragment and adds a new fragment. This means when
you press back button the fragment that got replaced will be created
with its onCreateView being invoked. Whereas add retains the existing
fragments and adds a new fragment that means existing fragment will be
active and they wont be in 'paused' state hence when a back button is
pressed onCreateView is not called for the existing fragment(the
fragment which was there before new fragment was added). In terms of
fragment's life cycle events onPause, onResume, onCreateView and other
life cycle events will be invoked in case of replace but they wont be
invoked in case of add.
In Short for your use case, you need to use add and if you don't want the fragment views to overlap then you might replace the Fragment B view background color with a solid color instead of transparent.
Also don't forget to add android:clickable="true" to the parent view of your second fragment so it catches the clicks and they don't get propagated to the fragment below. Something like this:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:focusable="true">
f you are adding the Fragments to the android.support.v4.app.FragmentManager you also have to call popBackStack() on the same FragmentManager.
This code should solve the problem:
if (getSupportFragmentManager().getBackStackEntryCount() > 0){
boolean done = getSupportFragmentManager().popBackStackImmediate();
}

Android fragment transition on back navigation to previous fragment

I have 2 fragments the first contains a button which on clicked opens a fragment with a ListView in it. I have a shared element transition for the button to transition into the new fragment (root layout) but I would also like to have this transition in reverse (the list fragment contracts into the button again).
However currently I detect the list item click and send an event to the Activity which pops the listview fragment off the backstack (popBackStackImmediate()) hence does not show the transition.
Is there a good way to allow back navigation while preserving reverse transition to work as well?
did you try this:
FragmentManager fm = getSupportFragmentManager();
fm.popBackStack();
fm.executePendingTransactions();
PS: use getSupportFragmentManager() if you're using the support library else use getFragmentManager().

How to keep state of Parent Fragment

I have a Fragment, in which I have a nested fragment. I've attached an image to illustrate. So I have child a nested, when I click button 1, I replace child A with child B, then on button 2 click I replace child B with child C. Now when I click on button 3, I replace the parent (Fragment 1 with Fragment 2), this is what I want to do.
When I hit the back button when on Fragment 2, I pop the backstack and I display fragment 1, the problem is child A is displayed, I need to figure out how to display child c when I go from Fragment 2 to Fragment 1.
I need to mention also that child c contains test results that are displayed in a grid view. Can someone help me do this please?
EDIT
Below is the code I'm using for the transactions for the child fragments (button 1 and button 2 click)
protected void nextNestedFragment(Fragment nestedFragment){
FragmentTransaction ft = getParentFragment().getChildFragmentManager().beginTransaction();
ft.setCustomAnimations(R.animator.enter_slide_in,R.animator.enter_slide_out,R.animator.close_slide_in, R.animator.close_slide_out);
ft.replace(R.id.nested_fragment_container, nestedFragment).addToBackStack(null).commit();
}
So for the above I pass in the next fragment I wish to navigate to within the parent fragment. Below is the code I use on button 3 press to navigate from Fragment 1 to Fragment 2:
protected void nextFragment(Fragment nextFrag){
FragmentTransaction ft = getParentFragment().getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.animator.enter_slide_in,R.animator.enter_slide_out,R.animator.close_slide_in, R.animator.close_slide_out);
ft.replace(R.id.fragment_container, nextFrag).addToBackStack(null).commit();
}
First, you need to know, that you have 2 different FragmentManager here (the default one, and ChildFragmentManager) and each with it's own back stack. And when you press a back button, you pop a back stack of your first FragmentManager, which shows you Fragment 1.
Second, when Fragment 1 is being popped from back stack onCreateView of that fragment is invoked. And I'm pretty sure you are creating a view there with a child A inside.
What you need to do is to save Fragment's state. There are a lot of questions here on how to do this correctly. Start from here.

difference between fragmentTransaction.add and fragmentTransaction.replace

What I already known is:
after fragmentTransaction.replace(), current fragment's onStop() function will be called
while fragmentTransaction.add() won't.
and after calling fragMgr.popBackStack();, we will return to previous fragment no matter fragmentTransaction.replace or fragmentTransaction.add() is used
So what does fragmentTransaction.replace do?
I can understand we can "add" a fragment opon a previous fragment and later return to previous fragment by popBackStack(), BUT:
if previous fragment is "replaced" by current fragment, I guess previous fragment is removed and current fragment is added in, how can it return to previous fragment when popBackStack() called?
You can add multiple fragments to a container and they will be layered one on top of the other. If your fragments have transparent backgrounds you will see this effect and will be able to interact with the multiple fragments at the same time.
This is what will happen if you use FragmentTransaction.add on a container. Your added fragment will be placed on top of your existing fragment.
If you use FragmentTransaction.replace(R.id.container,fragment) it will remove any fragments that are already in the container and add your new one to the same container.
You can also use the add method without a container id and your fragment will simply be added to the list of fragments in the FragmentManager and you can recall these at any time by their Tag value.
You can still return to a previous configuration IF you added the transaction to back stack. You can do this even if a previous operation removed a fragment. The removed fragment is remembered in the transaction and popping the back stack brings it back.
Two choices
Let's say you have a fragment container.
And, your task is to add a fragment into the container.
You can do this by calling any of the following methods
1) add(containerId,fragment)
2) replace(containerId,fragment)
But both methods differ in behavior !!!
Although both methods will add your fragment into the fragment container, their innards(internal working) differ based on the two possible states of the fragment container.
When fragment container
1) does not have any fragment in it.
2) already have one or multiple fragments attached to it.
Let's see what happens when we call add() and replace() method.
Case 1: When there is no fragment attached in a container
In this case, both methods will add the fragment to the container. So they will produce same effect.
Case 2: When the fragmentContainer already has fragment/fragments
add(): adds the new fragment on the top another fragment
replace(): removes everything then adds the new fragment
Example
So suppose the Fragment container has fragments[A->B->C].
Now you want to add a new fragment D.
add() method result will be [A->B->C->D]
replace() method result will be [D]
Relevant Link:
Check this Demo project for better understanding.

Hide previous Fragment when adding new one

I have 2 Fragment's - A and B.
In order to switch from Fragment A to Fragment B I'm using this function:
public static void swapFragments(FragmentManager fragmentManager, int containerViewId, Fragment newFragment) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(containerViewId, newFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
Let's say Fragment A takes the entire screen's area and Fragment B takes only the upper half of the screen.
The problem: When switching to Fragment B, the user is still able to see Fragment A at the lower half of the screen...
How can I hide Fragment A when switching to Fragment B ?
p.s: I don't want to use replace instead of add in the swap function above - I don't want Fragment A's onCreate() to be called each time the user navigate back from Fragment B to Fragment A...
Thanks in advance.
Could you maybe move Fragment A? E.g. slide it down when Fragment B appears? Simply move it outside the screen. Something like what's discussed in this question
Well, without any other option, I've just took care that Fragment B will occupy the entire screen so that Fragment A can't be seen.
More adjustments should have n=been done due to Android's bugs, such as: Google's stupid bug

Categories

Resources