Android: Move Fragment and add to backstack - android

I have a two pane layout.
I have a fragment on the left and a fragment on the right. Now I want to replace the left with the one on the right and create a new one on the right (i.e. I want to move the one on the right to the left, and create a new one on the right):
private FragmentManager fm; // assigned in onCreate
private MyListFragment rightSide; // assigned in onCreate
public void onClicked(Fragment fragment) { // callback
fm.beginTransaction().replace(R.id.left_side, rightSide).commit();
leftSide = rightSide;
rightSide = MyListFragment.newInstance();
fm.beginTransaction().replace(R.id.right_side, rightSide).commit();
}
Now at this point I get a IllegalStateException:
java.lang.IllegalStateException: Can't change container ID of fragment MyListFragment{300c6aae #1 id=0x7f070094}: was 2131165332 now 2131165331
Well I can circumvent this situation by
fm.popBackStackImmediate(null, fm.POP_BACK_STACK_INCLUSIVE);
fm.beginTransaction().remove(rightSide).commit();
fm.executePendingTransactions();
But I also want to have the ability to add it to the back stack. When I press back I would like to remove the one on the right and move the one from the left back to the right.
How can I make one transaction out of this with the ability to add it to the backstack and revert the transaction?

Do it all in one transaction, then call addToBackStack() to undo the whole thing when you press the back button:
private FragmentManager fm; // assigned in onCreate
private MyListFragment rightSide; // assigned in onCreate
public void onClicked(Fragment fragment) { // callback
MyListFragment newRightSide = MyListFragment.newInstance();
fm.beginTransaction()
.remove(rightSide)
.replace(R.id.left_side, rightSide)
.replace(R.id.right_side, newRightSide)
.addToBackStack(null)
.commit();
}

Related

Android: Replace sub fragment with it's parent fragment in main activity container

Imagine i have main activity that has viewpager. I have 2 fragments called (F1 & F2) that will transaction into viewpager.
Again imagine in F1 fragment i want to set a button. When clicking on button, i want to transaction other fragment call SUBF1 but not into F1 fragment.
My question is here!!! Is it possible to replace SUBF1 with it's parent means F1?My idea is that i want to replace sub fragment with it's parent fragment that has been kept on fragment's container in main activity?
final FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.details, new NewFragmentToReplace(), "NewFragmentTag");
ft.commit();
You can save the instance of current fragment, when you are
navigating from one fragment to other. When user press the back
button, you can open the specific fragment with the help of tag.
#Override
public void onBackPressed() {
String currentTag = currentFragment.getTag();
if(currentTag.equals(res.getString(R.string.fragmentTagTest)))
{
currentFragment = AnotherFragment;
replaceFragment() // integrate replace current fragment with new one.
}
}

Android fragment simple backstack

I have one activity containing one container that will receive 2 fragments.
Once the activity initialises i start the first fragment with:
showFragment(new FragmentA());
private void showFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.container, fragment, fragment.getTag())
.addToBackStack(fragment.getTag())
.commit();
}
Then when the user clicks on FragmentA, I receive this click on Activity level and I call:
showFragment(new FragmentB());
Now when I press back button it returns to fragment A (thats correct) and when i press again back button it show empty screen (but stays in the same activity). I would like it to just close the app (since the activity has no parent).
There are a lot of posts related with Fragments and backstack, but i can't find a simple solution for this. I would like to avoid the case where I have to check if im doing back press on Fragment A or Fragment B, since i might extend the number of Fragments and I will need to maintain that method.
You are getting blank screen because when you add first fragment you are calling addToBackStack() due to which you are adding a blank screen unknowingly!
now what you can do is call the following method in onBackPressed() and your problem will be solved
public void moveBack()
{
//FM=fragment manager
if (FM != null && FM.getBackStackEntryCount() > 1)
{
FM.popBackStack();
}else {
finish();
}
}
DO NOT CALL SUPER IN ONBACKPRESSED();
just call the above method!
addToBackStack(fragment.getTag())
use it for fragment B only, not for fragment A
I think your fragment A is not popped out correctly, try to use add fragment rather replace to have proper back navigation, however You can check count of back stack using:
FragmentManager fragmentManager = getSupportFragmentManager();
int count = fragmentManager.getBackStackEntryCount();
and you can also directly call finish() in activity onBackPressed() when you want your activity to close on certain fragment count.

How to show a Fragment managed by FragmentPagerAdapter?

I have a class derived from FragmentPagerAdapter and user swiping works fine (4 tabs), but I would like to show a page/tab/fragment from code. For example, when user taps a textview, I would like to switch to a specific fragment.
I've tried the following without success:
public void onClockClick(View v)
{
FragmentManager fm = getFragmentManager();
if (fm != null) {
fm.beginTransaction()
.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out)
.show(mainFragment)
.commit();
}
}
Am I barking up the wrong tree?
Well, if you know the position of the fragment you want to show then you can simply do: pager.setCurrentItem(pos)
This will automatically animate to the fragment at the desired position. Simple.
If you want to add another fragment to the existing FragmentPagerAdapter, then you'll need to first add the fragment's instance to that adapter and then call notifiyDataSetChanged on it.

Fragment Back button

I know how to add a Fragment to the backstack but how do I know, when the user presses the back Button, which fragment I left and which I went to? I need to do a certain action depending on this so I need to know from and to which fragment I am going. Specifically I need to know which fragment I left so if it is a certain fragment, I can remove a button.
Override onBackPressed in Activity:
#Override
public void onBackPressed(){
FragmentManager fm = getSupportFragmentManager();
Fragment f = fm.findFragmentById(R.id.content_frame); // get the fragment that is currently loaded in placeholder
Object tag = f.getTag();
// do handling with help of tag here
// call super method
super.onBackPressed();
}
You can add the Fragment like this :
ArticleMain articalemain = new ArticleMain();
getFragmentManager().beginTransaction().add(R.id.fragment_Top, articalemain, "MY_FRAGMENT").commit();
While Removing the Fragments do like this :
ArticleMain myFragment = (ArticleMain) getFragmentManager()
.findFragmentByTag("MY_FRAGMENT");
if (myFragment.isVisible()) {
// add your code here
myFragment.getFragmentManager().beginTransaction()
.remove(myFragment).commit();
}

Fragment Replacing Existing Fragment

I have the MainActivity, it contains ListFragment and framelayout, I am able to change the fragments on list on item click.
I have a problem to replace the existing Fragment1 with the new Fragment2, on button click of Fragment1, Fragment2 should replace the Fragment1, and should have the same ListFragment at left, and back buttons should be properly handled,this means when I am in Fragment2 and press back button it should show the same ListFragment and Fragment1.
You need to use .replace to switch the two fragments, you also need add add the original to the backstack so you can recall it, and you need to override the back key operation to function that way. It would look something like this (using code from one of my projects, using the support library):
To show your first fragment:
menu = new MenuFragment_Main(); // instantiate fragment
getSupportFragmentManager().beginTransaction().replace(R.id.pane, menu).commit(); // display fragment
To swap it for the new fragment and add it to the backstack:
ListFragment_ShopListItem shoplist = new ListFragment_ShopListItem(); // instantiate fragment
getSupportFragmentManager().beginTransaction().replace(R.id.pane, shoplist).addToBackStack(null).commit(); // replace original fragment with new fragment, add original to backstack
And to override the back key to go back to the previous fragment:
public void onBackPressed() {
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.popBackStack();
return;
}

Categories

Resources