I've got this issue where transitions from fragment A to B working fine but on backPress they do not. Looking around I saw many with this issue but none of the answers seems to help me out. I must be doing something wrong but have no idea what and I would love some help, it drives me nuts!
This is my logic:
Fragment A calling fragment B:
private void loadNextFragment(WeatherComplete[] weatherDataArrayList) {
FragmentManager fm = getFragmentManager();
MainFragment mf = MainFragment.newInstance();
mf.setVars(choosenCity, weatherDataArrayList);
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(R.anim.slide_in, R.anim.slide_iout, R.anim.slide_in, R.anim.slide_iout);
ft.addToBackStack(null);
ft.replace(R.id.frame, mf);
ft.commit();
}
Fragment B calling fragment C (Settings) from menu:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
final FragmentManager fm = getActivity().getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.setCustomAnimations(R.anim.slide_in, R.anim.slide_iout, R.anim.slide_in, R.anim.slide_iout);
ft.replace(R.id.frame, new Settings(), "settings");
ft.commit();
break;
I'm passing an object array from fragment A to fragment B, thus when clicking the back button on fragment C it will go back to fragment B but there is no object array to work with so in that case I want fragment C to go back to fragment A instead - I'm popping the backStack:
if (weatherDataObj == null) {
Log.d(TAG, "WEATHER DATA IS NULL");
FragmentTransaction ft = getFragmentManager().beginTransaction();
getFragmentManager().popBackStack();
// ft.remove(this);
ft.commit();
}
Try using this:
ft.setCustomAnimations(R.anim.slide_in, R.anim.slide_iout,
R.anim.slide_in, R.anim.slide_iout);
Related
I have three fragments (fragmentA, fragmentB, FragmentC). The code goes from fragmentA to fragmentB and then fragmentB to Fragemnt C.
When I press the back button I go from fragmentC to fragmentA.
After the back button is pressed fragmentA is displayed but you can also see fragmentC behind it.
fragmentA
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction;
ft.repalce(R.id.container, fragmentB)
.addToBackStack("Null")
.commit();
fragmentB
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction;
ft.repalce(R.id.container, fragmentC)
.commit();
fragmentC
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction;
ft.repalce(R.id.container, fragmentC)
.commit();
When the back button is pressed I want to go from fragmentC to fragmentA and not have fragment C displayed in the background
In addToBackStack use null as param , not "Null"
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction;
ft.repalce(R.id.container, fragmentB)
.addToBackStack(null)
.commit();
you can try this when replacing fragment
Fragment frag=null;
frag=new Navigation_Help();
if(frag!=null){
FragmentManager fragmentManager=getSupportFragmentManager();
FragmentTransaction ft=fragmentManager.beginTransaction();
ft.replace(R.id.sacreenarea,frag);
//for not to back previous fragment remove next nile
ft.addToBackStack(null);
ft.commit();
}
I tried using #ADM duplicate link, it would take me to the fragment A but if I loaded fragment B for a second time I would get double commit errors.
The solution that works for me is to restart the activity with the #Override onBackPressed(), this will reload the fragmentA by default.
Fragment B
FragmentManger fm = fragmentManager();
FragmentTransaction ft = fm.beginTransaction();
fm.replace(R.id.container, fragmentC, "fragmentC");
.commit();
fragmentC backbutton pressed
Activity
#Override
public void onBackPressed() {
if(getSupportFragmnetManager().findFragmnetByTag("fragmentC") !=null) {
Intent myIntent = new Intent(this, Activity.class);
startActivity(myIntent);
finish();
} else {
super.onBackPressed();
}
}
This solution will only work if you want to go back to the first fragment loaded by the Activity, so it may not be the best solution out there but it worked for me.
I am beginner in android and trying to develop an android app in which I stuck in back navigation. My issue is :
How to manage backstack with activities and fragments.
A1 activity with frag1 calls A2 activity and A2 activity displays a user list where on click of a list to check user profile, call to A1 Activity with Frag 2.
On opening of Frag2 of A1 activity, We are using intent flag: flag_activity_reorder_to_front and adding frag1 to backstack with FragmentManager transaction
Now IF I click on back then It shows A1 Activity with frag1 instead of A2 Activity.
IF I don't add frag1 into backstack then on back, It works with first back but on second back it exits from the app.
Any suggestions?
Try using single activity and handle all fragment transactions in it using an interface. Activity should implement this interface.
Example:
public interface FragChanger {
int NEXT_FRAGHELLO =1;
int NEXT_FRAGSET = 2;
int NEXT_FRAGSELECT =3;
int NEXT_FRAGLOG=4;
int NEXT_FRAGCHAT=5;
void onFragmentChange(int nextFrag);
}
The following should be in Your activity:
#Override
public void onFragmentChange(int nextFrag) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
switch (nextFrag){
case NEXT_FRAGHELLO:
break;
case NEXT_FRAGSET:
FragSet fragSet = new FragSet();
ft.replace(containerId,fragSet,"fragset");
ft.addToBackStack(null);
ft.commit();
break;
case NEXT_FRAGSELECT:
FragSelect fragSelect = new FragSelect();
ft.replace(containerId,fragSelect,"fragselect");
ft.addToBackStack(null);
ft.commit();
break;
case NEXT_FRAGCHAT:
FragChat fragChat = new FragChat();
ft.replace(containerId,fragChat,"fragchat");
ft.addToBackStack(null);
ft.commit();}
break;
case NEXT_FRAGLOG:
ft.replace(containerId,fragLog,"fraglog");
ft.addToBackStack(null);
ft.commit();
break;
}
Handling back in your activity:
#Override
public void onBackPressed() {
Log.d(TAG,"button back pressed");
//Check which fragment is displayed an do whatever you need
//for example like this
if (getSupportFragmentManager().findFragmentById(containerId) instanceof FragLog){
Fragment fl = getSupportFragmentManager().findFragmentByTag("fraglog");
if (fl !=null){
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.remove(fl);
ft.commit();
return;
}
}
}
Of course, this is only an example, but may be useful in Your case
Hi I have 5 fragments Now first time when I go to Activity of that fragments then default First fragment is called,then on first Fragment there is a button by clicking that button I go to the second fragment,similarly in Second fragment There is a button and clicking that button I go to the third fragment and so on.
Now My Question is that Current I am on Fifth fragment ,Now I want to go fifth fragment to second fragment,what should I do for this?
Can any one please tell me?
You can pop the fragment by name. While adding fragments to the back stack, just give them a name.
fragmentTransaction.addToBackStack("frag2");
Then in fragment5, pop the back stack using the name ie.. frag2 and include POP_BACK_STACK_INCLUSIVE
someButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fm = getActivity()
.getSupportFragmentManager();
fm.popBackStack ("frag2", FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
});
Here is the method to add and replace fragment.
public void addReplaceFragment(Fragment fragment, int addOrReplace) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
switch (addOrReplace) {
case addFragment:
transaction.add(R.id.frame_containerforsearchable, fragment);
transaction.commit();
break;
case replaceFragment:
transaction.replace(R.id.frame_containerforsearchable, fragment);
transaction.commit();
break;
default:
break;
}
}
call of fragment is..
addReplaceFragment(currencyFragmentWithSearch, replaceFragment);
replaceFragment integer variable
currencyFragmentWithSearch Fragment instance
You can always do this :)
getActivity().getSupportFragmentManager().replace(R.id.yourFrameLayout,new Fragment2(),"FRAG2");
OR
Fragment fragment = getActivity().getSupportFragmentManager().findFragmentByTag("FRAG2");
getActivity().getSupportFragmentManager().replace(R.id.yourFrameLayout,,"FRAG2");
Try this code:
Fragment fragment = new SecondFragmentName();
FragmentManager fm = getActivity().getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.commit();
just small correction to mudit_sen code. It is working, only if you add .beginTransaction. Thank you.
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.FrameLayoutId,new FragmentName()).commit();
I've got the next code to switch between 4 fragments in a container [Main, A, B, C].
I need back button to go back to [Main] no matter how the user has navigated through fragments. For example, if I go [Main] >> [A] >> [C] when pressing back should go to [Main].
But I'm not getting the desired result. I think that I'm not doing well the coparisson between fragments.
Launcher MainFragment = new Launcher();
public void switchFragment(Fragment pFragment) {
FragmentManager fm = getSupportFragmentManager();
Fragment currentFragment = fm.findFragmentById(R.id.fragment_container);
if (pFragment == MainFragment){
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, pFragment).commit();
}
else if (currentFragment == MainFragment && pFragment != MainFragment){
//Fragment fr = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, pFragment).addToBackStack(null).commit();
}
else {
//Fragment fr = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, pFragment).commit();
}
currentFragment = pFragment;
}
UPDATE--
I've seen this way is working better, but still makes issue. If I navigate through some fragments without returning back to the Main fragment, when I press back it doesn't go back. It's like if there was some issue with the popbackstack().
public void switchFragment(Fragment pFragment) {
FragmentManager fm = getSupportFragmentManager();
Fragment currentFragment = fm.findFragmentById(R.id.fragment_container);
if (pFragment.equals(MainFragment)){
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, pFragment).commit();
}
else if (currentFragment.equals(MainFragment) && !pFragment.equals(MainFragment)){
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, pFragment).addToBackStack(null).commit();
}
else {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, pFragment).commit();
}
}
This functionality can be achieved by removing .addToBackStack from your fragment transactions.
Here is the Android reference for back stack functionality within fragments: http://developer.android.com/training/implementing-navigation/temporal.html#back-fragments
I finally get the dessired result just replacing the fragment I want on the back_key onClickListener:
final OnClickListener goBack = new OnClickListener() {
#Override
public void onClick(View v) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, MainFragment).commit();
}
};
This way, if In the future I need to go back to another fragment instead of the Main, I'll just add a condition to compare fragment tags and do something depending the tag.
I want to do the following. There are two fragments first and second. Necessary make the transition between them. When I go from first fragment in the second, first stored in the stack. When I click the Back button the second fragment is removed and returned first fragment from the stack. Again I can not go in the second fragment - it has been deleted. How can I solve this problem?
In main activity (callback for Fragment1):
#Override
public void onNavigate() {
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment1 newFragment1 = (Fragment1) getFragmentManager().findFragmentByTag("frag_1");
Fragment2 newFragment2 = (Fragment2) getFragmentManager().findFragmentByTag("frag_2");
ft.replace(R.id.main, newFragment2);
ft.remove(newFragment1);
ft.addToBackStack(null);
ft.commit();
}
Fragments I added dynamically:
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.main, new Fragment1(), "frag_1");
ft.add(R.id.main, new Fragment2(), "frag_2");
ft.commit();
I solved this problem :). I hide first fragment and add transaction to the back stack. When I click button Back I return to fragment
#Override
public void onNavigate() {
FragmentTransaction ft = getFragmentManager().beginTransaction();
Fragment1 newFragment1 = (Fragment1) getFragmentManager().findFragmentByTag("frag_1");
ft.hide(newFragment1);
ft.addToBackStack(null);
ft.commit();
}