I need to create navigation of fragments like in Gmail app. It's like: we have one main fragment A, we can open another fragment (B,C,D...) from navigation drawer, and when we open new fragment, it`s open on top of main fragment, and when press back button, in all cases we come back to main fragment A, don't depend of count new opened fragments. It's seems, first main fragment A we use add method(int FragmentTransaction) without adding to fragment backStack. Then, next fragment B we use method add too, with adding to back stack. And when I need to open another one (Fragment C), I need to replace second fragment B. But, when I use method replace(), replaced all container, and main fragment A not showing when back button pressed from fragment C or B and app close. So, the question is: how to replace only fragment B or C, without losing fragment A?
A valid solution would be to have two container framelayouts in your activity. The first one (which will below the other one) contains your fragment A. Everything you open will be added/replaced in the second container.
Another solution is to include the fragment A statically in your layout and have your container framelayout on top of it where you add your fragments B, C, D etc.
open fragment Like this
HighlightFragment highlightFragment=new HighlightFragment(FirstReaderScreen.this); //Your fragment
getSupportFragmentManager()
.beginTransaction()
.add(R.id.LL_Fragment, highlightFragment) // LL_fragment is container
.addToBackStack(null)
.commit();
and in Activity OnBackPress
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}
Related
such as Fragment A -> Fragment B -> Fragment C -> Fragment D.
how can i restart Fragment A just like Activity singleTask launch mode.
The way I figure out that Fragment D invoke popBackStack 4 Time And add a New Fragment A to backstack. Using Fragment animation to make it look like back to FragmentA. But it's just a visiual cheating.
And someTime, I don't know how many times I have to popBackStack.
Is there any way to do that without using Jetpack Navigation?
Oh, I found the function can solve this question.
popBackStack(String name, flag)
I use it wrongly before which make it didn't work. (what a stupid mistake, I forget to set Framgent name in backstack)
We need to set the fragment name while add to fragment backstack.
After we set the name, popBackStack(name, flag) can work.
while flag = 0, the target Fragment will not be popped;
while flag = 1, the target Fragment will be popped too;
public void addFragmentToBackStack(Fragment fragment) {
getSupportFragmentManager().beginTransaction()
.addToBackStack(fragment.getClass().getName())
.replace(R.id.fl_container, fragment, fragment.getClass().getSimpleName())
.commitAllowingStateLoss();
}
I'm using multiple fragments inside an activity like this flow: Fragment A has a list on it's item click Fragment B opens and it also has a list opens Fragment C which has a list Open another Activity , The problem is when I go back from the other Activity I found Fragment A is opened, How I restore the last Fragment C when go back from the other activity?
here is the code of replacing Fragment inside my activity
protected void showFragment(Fragment fragment) {
String TAG = fragment.getClass().getSimpleName();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.container_home, fragment, TAG);
fragmentTransaction.addToBackStack(TAG);
fragmentTransaction.commit();
}
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.
Use add instead of replace
fragmentTransaction.add(R.id.container_home, fragment, TAG);
I had the same issue solved using the above code.
You can use
fragmentTransaction.addToBackStack(null);
instead of,
fragmentTransaction.addToBackStack(TAG);
Hope Your problem will solve.
Basically, I want to open a fragment from Activity. Everything worked fine (activity button opens the fragment and the fragment shows), until I miss-clicked outside the fragment's layout where one of the Activity button is located and it did its onClick method. That's why I wondered why is my Activity still active.
this is how I open the fragment from Activity
I tried using .add instead of .replace still the same.
#OnClick(R.id.login_register_lbl)
public void registerAction(View view) {
// TODO register transition...
FragmentManager fragmentManager = (LoginActivity.this.getFragmentManager());
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
RegisterFragment fragment = new RegisterFragment();
fragmentTransaction.replace(R.id.fragment_register_holder, fragment);
fragmentTransaction.commit();
}
In fragment layout in root element set "background" , "clickable=true" & Focusable="true".
In my opinion you can achieve this functionality by 2 ways:
Open a dialog fragment in full screen mode to avoid accidentally clicks on activities views.
If you wanted to show both fragment's and activity's views at the same time then, on click of your activity's button which opens the fragment, disable it by yourbutton.setenabled(false); and when you wanted to close the fragment enable that button again.
My app has 3 UI levels, each level has its own fragment, A -> B -> C.
I wish to optionally allow my app user to navigate straight to the top level fragment i.e. from C -> A without invoking B.
i.e., I still want to allow the user to go from C->B if they press the back button, but in the C fragment, I have a "Home" button, which takes them directly to A. This is the operation where I want to flush the backstack.
Additionally, I want the user to be able to go from B->A using the back button, hence I'm adding A and B both to the backstack.
I have tried the options from this SO post but in each case, onCreateView gets invoked for each fragment, even if I use fm_.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
Also checked this thread, it seems to recommend using popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
Can anyone please suggest a way to pop the entire backstack without having the onCreateView called on popped fragments?
Dont add backStack line for going from fragment B->C
while going from A->B use
HighlightFragment highlightFragment=new HighlightFragment(FirstReaderScreen.this);
getSupportFragmentManager()
.beginTransaction()
.add(R.id.LL_Fragment, highlightFragment) // LL_Fragment is container
.addToBackStack(null)
.commit();
while going B->C use
HighlightFragment highlightFragment=new HighlightFragment(FirstReaderScreen.this);
getSupportFragmentManager()
.beginTransaction()
.add(R.id.LL_Fragment, highlightFragment)
.commit();
dont add line .addtobackstack(null)
This worked for me
i estimate you're using replace fragment.
try to use begintransaction.hide / show to manage many fragment inside 1 activity if you don want to popback
//on Activity
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(containerId, new FragmentA(), fragmentA.getClass().getSimpleName());
fragmentTransaction.commit();
//inside fragment A to jump fragment without PopBackStack
getFragmentManager().beginTransaction().hide(this).commit();
getFragmentManager().beginTransaction().show(new FragmentB()).commit();
This is working for me when needing to clear the back stack for tab switches in BottomNavigationView
public void clearBackStack() {
int backStackEntryCount = mFragmentActivity
.getSupportFragmentManager()
.getBackStackEntryCount();
for (int i = 0; i < backStackEntryCount; i++) {
mFragmentActivity.getSupportFragmentManager().popBackStack();
}
}
My App has only one activity and lots of fragments.
In my activty's XML, I just have a FrameLayout on which I replace/add/hide/show various fragments.
Imagine Fragment A is the first fragment the user sees when they open the app.
Click something in Fragment A to launch Fragment B and click something in Fragment B to launch Fragment C.
So the navigation is can be illustrated as follows :
Fragment A --> Fragment B --> Fragment C
I want to launch the app and show Fragment C directly from notification.
However, how can I provide back navigation from Fragment C, as such clicking back would go to Fragment B and clicking back again go to Fragment A ?
i.e How can I inject the following stack structure ?
Fragment A <-- Fragment B <-- Fragment C
Yes, you can do this. Since support library v26 you can build the stack with fragments without significant cost.
In your activity make the following:
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, new FragmentA())
.addToBackStack("fragmentA")
.setReorderingAllowed(true)
.commit();
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, new FragmentB())
.addToBackStack("fragmentB")
.setReorderingAllowed(true)
.commit();
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, new FragmentC())
.addToBackStack("fragmentC")
.setReorderingAllowed(true)
.commit();
Keep in mind that FragmentA and FragmentB will behave in a bit different way after pressing back on FragmentC due to setReorderingAllowed. onCreateView won't be called for FragmentA and FragmentB after they were added to stack, only in FragmentC onCreateView will be called. For FragmentA and FragmentB only onCreate will be called.
What you can do is -
Use a notification intent in which you pass a string. In your main activity if you receive that string make a fragment stack of A, B and C.
Else if you don't get the intent just continue your flow as it is.