I have an activity with 4 fragments. on fragment 3 there is a button when i click on that button i go to some other activity(Like TestActivity). I use this code to go from fragment 3 to that TestActivity:
startActivity(new Intent(getActivity(), TestActivity.class));
When i press back button on TestActivity it redirect me to the 1st Fragment(Default) of Main Activity. I want that when user press back on TestActivity to again come to Fragment 3. Please suggest me how i achieve this behaviour. Thanks
First of all you should know it has difference between fragment and activity back stack.
In change your fragment you should use add addToBackStack("name") , something like this :
KOTLIN :
In fragment :
requireActivity().supportFragmentManager.beginTransaction()
.replace(R.id.framelayout_main_fragmentContainer,SecondFragment())
.addToBackStack("first")
.commit()
In activity :
supportFragmentManager.beginTransaction()
.replace(R.id.framelayout_main_fragmentContainer,Firstfragment())
.addToBackStack("first")
.commit()
JAVA :
getFragmentManager().beginTransaction().
replace(R.id.framelayout_main_fragmentContainer, Firstfragment()).
addToBackStack("first").commit();
Related
private fun navBottomClick() {
bottomNavigationView?.setOnItemSelectedListener {
when(it.itemId){
R.id.workout ->{
val fragmentTransaction:FragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.container,WorkoutFragment(),"WORKOUT")
//fragmentTransaction.addToBackStack("WORKOUT")
fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
fragmentTransaction.commit()
}
R.id.steps ->{
intent = Intent(this,StepsActivity::class.java)
startActivity(intent)
}
}
true
}
}
override fun onBackPressed() {
super.onBackPressed()
}
}
When I pressed back, my app is closed. I want to make it go from a fragment to the main acitvity.
You have misunderstood the concept of Fragments and Activity . The issue you facing of the application getting close on navigating back from the fragment because it is the last fragment present in the stack .
Concept :
Basically , an Activity acts as an container for all of your Fragments . So , you create an activity and create a Fragment-Container / FrameLayout in that Activity wherein you assign the Fragments. So , Consider this example :
Here you can see, there are two fragments and both of them are placed in only one Activity . So this clarifies that Activity acts as an container for fragments .
What causes the Issue of Application being closed :
So what happens is when you navigate back from the last fragment , since it does not have anywhere to go back it closes the application .
Solution :
So if you want to get your Activity on navigating back on the last fragment to the Activity then , you need to override the popBackStack() method on the last Fragment and in there you need to disable the FragmentContainer / FrameLayout view, in this way you can get your activity back .
Recommended Solution : Move all the stuffs that you want to show at the end from your Activity to another Fragment and popBackStack() to that Fragment, doing such maintains the Single Activity principle .
You should have a popbackstack to send the screen correctly. Check if your fragment has implemented inside of this activity, if yes, really that will be closed.
Don't forget that fragment is inside of the one activity.
You need to un-comment this line
//fragmentTransaction.addToBackStack("WORKOUT")
then it will work as there is no stack maintained activity can't go back to previous fragment and will close the activity.
I have a single activity and 4 menu. suppose I click on home menu and add a fragment lets say FragmentA and then from FragmentA I add another fragment say FragmentB now when I press back button it returns back to HomeFragment instead of FragmentA. why is so?
You can do it Using popBackStack(); like
override fun onBackPressed() {
val manager: FragmentManager = supportFragmentManager
if(manager.backStackEntryCount > 0){
manager.popBackStack()
}else{
super.onBackPressed()
}
}
The back button is used to come back to previous Activity only not Fragment.
In my App I have a MainActivity where I start a CalcActivity which includes two consecutive Fragments. I inflate those Fragments successively by
fun replaceFragment(resId : Int, fragment : Fragment){
this.supportFragmentManager?.beginTransaction()?.replace(resId, fragment)?.addToBackStack(null)?.commit()
}
So in my CalcActivity:
I inflate CalculationFragment with replaceFragment(R.layout.frag_calc, CalculationFragment())
collect data and calculate a result in the first fragment.
When I have a result I call a callback from CalculationFragment in my Activity
In that callback (back in CalcActivity) I replaceFragment(R.layout.frag_result, ResultFragment()) to show my results.
This is working so far, BUT
whenever I backpress it goes back to CalculationFragment ?!
I was exprecting to go back to the MainActivity..
MainActivity
+-> CalcActivity
+-> CalculationFragment
+-> ResultFragment
How can I go back to MainActivity?
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();
}
}
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.