Hi Following my code to show detail fragment from list fragment
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.FragmentContainer1, DealFragment.newInstance(dealItems, position, currentPage, totalCount)).addToBackStack(null).commit();
Now when I press back button I get new ListFragment.ListFragmnt state is not saved.
I referred to some stack questions but haven't got right answer
I tried below code but it causes issues when app goes in background and is killed by system(Like I am opening chrome from my detail view and when I go back from chrome my app is closed and minimised) FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.hide(getActivity().getSupportFragmentManager().findFragmentById(containerId));
ft.add(containerId, detailFragment);
ft.addToBackStack(null);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
Any solution on this problem when I move to ListFragment to detail hot maintain state of detail fragment.
I have referred this link from stack overflow here is the link
I want functionality same as Gmail app when we go from list to detail and come back to list fragment. Scroll position and everything is maintained which is not happening in my case
Try this :
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
getSupportFragmentManager().popBackStack();
} else {
this.finish();
}
}
In your activity set the first fragment:
ListFragment listFragment = new ListFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.add(R.id.FragmentContainer1, listFragment );
transaction.addToBackStack(null);
transaction.commit();
Then in listfragment call details fragment:
DetailFragment detailFragment = new DetailFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.FragmentContainer1, detailFragment);
transaction.addToBackStack(null);
transaction.commit();
Related
I have two fragments one list and one detail fragment. On list item click I a hiding list fragment and adding detail fragment on back press detail fragment is popped automatically I am just calling super.onBackPressed() but issue is it is creating so many references of detail fragments resulting is memory leaks
Following is my code
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.hide(this);
ft.add(containerId, detailFragment, "detail");
ft.addToBackStack("detail");
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();
I don't want to view to be recreated view when user press back button on detail fragment thats why I used above approach. Also with current implementation when I press back button recylerview scroll possition and other data I don't have to save
My Activity has only following code it inflates list fragment
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.FragmentContainer1, ListFragment.newInstance(), TAG).commit();
}
I think what you are doing wrong is that you are adding fragments each time to the container again and again by calling add method:
In your case you should use replace method and add your list fragment to the backstack. Here's how you should start your detail fragment:
FragmentManager fm = getFragmentManager();
fm.beginTransaction()
.replace(R.id.container, new DetailFragment())
.addToBackstack(null)
.commit();
To get back to your list fragment, which is in the back stack, just call:
fm.popBackStack();
EDIT:
Try this to show your list fragment:
protected void displayListFragment() {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (listFragment.isAdded()) {
ft.show(listFragment);
} else {
ft.add(R.id.flContainer, listFragment, "ListFragment");
}
if (detailFragment.isAdded()) {
ft.remove(detailFragment);
}
ft.commit();
}
And this to show your detail fragment:
protected void displayDetailFragment() {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (listFragment.isAdded()) {
ft.hide(listFragment);
}
if (!detailFragment.isAdded()) {
ft.add(R.id.flContainer, detailFragment, "DetailFragment");
}
ft.commit();
}
I have the following issue. My application has 2 fragments, the first one that is executed show a list of items, when you tap on an item, shows a detail fragment.
I also have a NavigationDrawerActivity, with the following methods to handle the stack of fragments.
private void changeFragment(int pos, Fragment fragment, boolean addToBackStack) {
Fragment f = getSupportFragmentManager().findFragmentByTag(String.valueOf(pos));
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
mCacheServices.setmFragmentTag(String.valueOf(pos));
ft.replace(R.id.container, fragment, String.valueOf(pos));
if ((addToBackStack)) {
ft.addToBackStack(STACK_KEY);
}
ft.commit();
}
The problem i am facing is when i am in the DetailFragment, and i rotete the device, it goes to the ItemList fragment, which is the firs fragment excuted by the app. What can i do to mantain on the DetailFragment when i rotate the device?
Thanks!
you can save the state of the fragment and then re-create it. Go through this for more details
http://developer.android.com/guide/topics/resources/runtime-changes.html
hope this helps.
I have gone through many stackoverflow question before writing this. i am so confused about this guy Backstack in fragment.
I have Added three fragment on the same container inside an Activity
Fragment 1 :
private void addLandingFragment() {
landingPageFragment = LandingPageFragment.newInstance();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add( R.id.container, landingPageFragment, LANDING_PAGE_FRAGMENT_TAG );
transaction.commit();
}
Fragment 2 :
public void addIntrofragment() {
fragment2 = IntroFragment.newInstance();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace( R.id.container, fragment2, INTRO_PAGE_FRAGMENT_TAG);
transaction.addToBackStack(fragment2.getClass().getName() );
transaction.commit();
}
Fragment 3 :
public void onGetStartedClicked() {
fragment3= ConnectFragment.newInstance();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace( R.id.container, fragment3,CONNECT_PAGE_FRAGMENT_TAG );
transaction.commit();
}
Now what I want is when user presses back button on fragment 3 it should come on very first fragment so I have overrided the onBackPressed() method.
#Override
public void onBackPressed() {
manager.popBackStack(fragment2.getClass().getName() ,FragmentManager.POP_BACK_STACK_INCLUSIVE );
}
but nothing happening on screen it keeps fragment 3 running.
UPDATE
When I am navigating from
fragment1 > fragment2
and presses back button on fragment2, I am coming to fragment1 but if move from
fragment1 > fragment2> fragment3
I am getting the stack entry count 1 on onBackPressed() method but on device screen it still shows fragment3. Now pressing back button again will exit me from app but fragment1 wont come on screen. So puzzling why it is happening ?
Any solution to achieve this.
calling replace() will remove the previous fragment, Fragment 1 should be called using replace(), and Fragment 2 & 3 should be called using add(), you should also add the last transaction to back stack (calling Fragment 3)
Like this:
Fragment 1:
private void addLandingFragment() {
landingPageFragment = LandingPageFragment.newInstance();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace( R.id.container, landingPageFragment, LANDING_PAGE_FRAGMENT_TAG );
transaction.commit();
}
Fragment 2:
public void addIntrofragment() {
fragment2 = IntroFragment.newInstance();
FragmentTransaction transaction = manager.beginTransaction();
transaction .hide(LandingPageFragment.this);
transaction.add( R.id.container, fragment2, INTRO_PAGE_FRAGMENT_TAG);
transaction.addToBackStack(fragment2.getClass().getName() );
transaction.commit();
}
Fragment 3:
public void onGetStartedClicked() {
fragment3= ConnectFragment.newInstance();
FragmentTransaction transaction = manager.beginTransaction();
fragmentManager.popBackStackImmediate(); // to remove fragment 2
transaction.add( R.id.container, fragment3,CONNECT_PAGE_FRAGMENT_TAG );
transaction.addToBackStack(fragment3.getClass().getName() );
transaction.commit();
}
finally your onBackPressed should be like this:
#Override
public void onBackPressed() {
fragmentManager.popBackStackImmediate();
fragmentTransaction.show(LandingPageFragment.this);
}
therefore your onBackPressed will always pop the top fragment on the stack (Fragment 3), and since Fragment 2 was already popped before adding Fragment 3, then onBackPressed will display the very first fragment.
Thanks Silvia.H for you support. I have solved my problem and found it as the best possible solution for me.
The only mistake I did was, I did not add fragment3 in backstack
So the only changes required was
public void onGetStartedClicked() {
fragment3= ConnectFragment.newInstance();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace( R.id.container, fragment3,CONNECT_PAGE_FRAGMENT_TAG );
transaction.addToBackStack(ConnectFragment.class.getName() );
transaction.commit();
}
Now this makes you clear that in order to use popBackStack with name like
manager.popBackStack(fragment2.getClass().getName() ,FragmentManager.POP_BACK_STACK_INCLUSIVE );
you have to keep that transaction in backstack from where you are actually pressing the back button.
I have made one more small change in onBackPressed() method which allows the app to exist when user presses back button on fragment1.
My onBackPressed() look like this now
#Override
public void onBackPressed() {
if( manager.getBackStackEntryCount() > 0 ) {
getSupportFragmentManager().popBackStack(
scoreTrackerIntroFragment.getClass().getName(),
FragmentManager.POP_BACK_STACK_INCLUSIVE );
}else {
super.onBackPressed();
}
}
Woop! Now I am clear about this "Backstack" guy.
when I click on the back press on real device it went to the home page not to the previous page ,here I am Using fragments how to solve that issue
In First Fragment
NotesFragment notes = new NotesFragment();
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.day_fragment_mainLayout, notes);
transaction.addToBackStack(null);
transaction.commit();
in Second Fragment
DayFragment day = new DayFragment();
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.addToBackStack(null);
transaction.replace(R.id.day_fragment_mainLayout, day);
transaction.commit();
in Third Fragment
ItemsFragment items = new ItemsFragment();
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.addToBackStack(null);
transaction.replace(R.id.day_fragment_mainLayout, items);
transaction.commit();
when i click on backpress button its goes to the home page,bt i need prevoius page.
note: btnclick i am using to navigating fragments one to one
You could achieve it by using FragmentTransaction's add() method, and then override onBackPressed where you have to pop your FragmentManager's back stack. This will result in the behaviour you described.
You cannot go back because you didn't open any new activity. OnBackPressed is moving you to the previous activity stored in the stack. If you want to go back to the previous fragment, you have to store the previous fragment somewhere and then use:
#Override
public void onBackPressed() {
// here you should change the fragment
transaction.replace(YOUR_PREVIOUS_FRAGMENT, items);
transaction.commit();
}
Thanks for attention!
I am developing an android app with lots of fragments in it. But I am facing problems in switching between them.
Lets say I have a Fragment A now I want to go to Fragment B, for this I am doing like this--
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager
.beginTransaction();
Fragment fragment = new Fragment_B();
transaction.add(R.id.frameLayout, fragment);
transaction.addToBackStack(null);
transaction.commit();
I reach Fragment B successfully. Now I have to go to Fragment C from here, for this again I am doing the same thing.
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager
.beginTransaction();
Fragment fragment = new Fragment_C();
transaction.add(R.id.frameLayot, fragment);
transaction.addToBackStack(null);
transaction.commit();
I do this successfully also. Now I have to revert back to Fragment B, for this I do -
getFragmentManager.popbackstack();
This brings me back to Fragment B. But when I do the same to go to Fragment A now, it causes NullpointerException.
What I am doing wrong here. Why does this run perfectly for the first time but fails at the second time? Please help.
I think you have to check first there are fragment available in backstack or not. follow my below code:
if(manager.getBackStackEntryCount()>0){
manager.popBackStack();
manager.beginTransaction().commit();
}
Thats it...
and yes you do not add fragment a to backstack initally so crosscheck that..
fragmentTransaction.addToBackStack("tag");
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 1) {
getFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
}