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?
Related
I'm using MVP in my project. I have an activity. Inside this activity I'm showing fragment. Fragment contains some data, edit text, buttons etc. From this fragment it is possible to navigate to another fragment. Here is my code for showing another fragment:
getParentFragmentManager()
.beginTransaction()
.replace(R.id.main_container, secondFragment)
.addToBackStack(null)
.commitAllowingStateLoss();
Next, when I try to go back from fragment 2 to fragment 1, my fragment one is re-created.The method onViewCreated() is called again with saveedInstanceState = null. Also in the onViewCreated() I call presenter.onCreate(savedInstanceState) and because of this, all requests that should be called when I first enter the fragment are re-called when I back to first fragment.
As far as I understand, when calling a .replace(container, fragment), I cannot avoid recreating the fragment view, but in this case, how can I save all my data in the presenter so that I do not re-execute all requests when returning to the fragment?
P.S. With .add() fragment is not recreated. But in my activity I have toolbar with title, and I don't need it to show in my second fragment. When I open my second fragment with .replace() toolbar is not showing, but when open with .add() toolbar is showing.
Use Fragment Result API :
For implemention this method set - setFragmentResultListener - in source fragment and also set - setResult() and finish() - in destination fragment
Note 1 : for having clean code i suggest you to use FragmentTransaction class in:
https://github.com/mahditavakoli1312/FragmentTransaction---mahdi-tavakoli
Note 2 : use Navigation for navigate betwin fragments and activities Instead tranastion
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 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();
I have FragmentA and FragmentB.
I added FragmentA to an Activity using the add (not replace) fragment transaction. A button in FragmentA makes a callback to it's Activity which then makes an add fragment transaction to add FragmentB.
I update the title of the ActionBar with the value of a variable (which is fetched online) in FragmentA and FragmentB.
After the fragment transactions I outlined above, if I'm in FragmentB and I press the back button (now I'm in FragmentA), the title of the ActionBar is still that of FragmentB.
So I wanted to know which lifecycle methods are called on FragmentA when I'm coming from FragmentB so I can update the Actionbar from there.
I don't know if there is a method that is called when backstack is popped, but what you can do is overwrite onBackPressed in your Activity class that contains the fragments, call fragmentManager.popBackStackImmediate. This method returns a boolean, if it's true, then you went from fragmentB to fragmentA (or to any other previous fragment). You are in your activity class, so you can update your ActionBar anyway you'd like.
One more thing, if fragmentManager.popBackStackImmediate is true, don't call super.onBackPressed()!!!
onStart() method is clearly the adapted one. When comming from backstack, it will always be called.
I have an activity which holds the fragment A and Fragment A hold a list view and button, when I pressed the button it directs to another fragment B.
My question is which method I need to override in fragment A so when I pressed the back button, I can re-populate the list view inside. Or is there another simple way I can make it ?
Until now I tried to override the onResume and onStart, it didnt work. Btw I cant override the back button pressed in Fragment B because in that case I cant reach ui components in fragment B and getting a null pointer normally.
Thanks in Advance.
Your will get NO notice when the previous fragment is show again.
But you can override the onBackPressed() method of the fragment's parent activity like this:
#Override
public void onBackPressed() {
//1.find your fragment A by tag, this tag is supplied
//when you using FragmentTransaction.add(int id, Fragment fragment, String tag)
//the you can find fragment by this way
//FragmentA fragment = getSupportFragmentManager().findFragmentByTag(name)
//2.call some method of it!
}