Android - Back button and fragment backstack not w

2019-03-20 22:43发布

问题:

I'm developing a simple fragment-based application with a singe FragmentActivity. Each 'screen' of the application is contained in a fragment and all fragments are added to the container layout at application startup.

// Set up fragments in Main Activity
fragMan = getFragmentManager();
FragmentTransaction ft = fragMan.beginTransaction();
ft.add(R.id.fragment_container, settingsFragment);
ft.add(R.id.fragment_container, mapFragment);
ft.add(R.id.fragment_container, tracksFragment);
ft.add(R.id.fragment_container, waypointsFragment);
ft.commit();

Transitions are accomplished by hiding the currently visible fragment, then showing the appropriate fragment.

ft = fragMan.beginTransaction();
ft.show(mapFragment);
ft.addToBackStack(null);
ft.commit();

This all works fine, but when the back button is pressed, the application exits, regardless of which screen is visible or what previous transactions have been added to the back stack.

I've checked to make sure that the back stack is properly accumulating records and tried many different variations of transition methods such as replacing fragments rather than hiding/showing them, creating new instances of fragments rather than storing them in variables, etc. As far as I can tell, my code matches all the tutorials and examples I can find, and I haven't even been able to find any similar questions/examples of similar problems, presumably because the standard implementation 'just works' for others.

I suspect it may be a problem at the application level such as a property in my manifest (which I've investigated pretty thoroughly) or something inherent to the way my application is set up which prevents the back button from functioning properly. I can override onBackPressed to handle the transitions manually, but this seems like a very ugly workaround. Any ideas as to why this might not be behaving as expected? By the way this is on a Nexus 7 running Jelly Bean.

回答1:

Check if you are using FragmentActivity(from support library) instead of Activity. This will cause backstack and transition problem.



回答2:

I'm not sure if this will solve your problem but I dont think you need to add all the fragments to begin with.

I've also noticed (at least with the compatibility library) that the replace method seems to be very buggy, so best to remove the existing fragment first and then add the new one.

Here is the bit of code I use to change a fragment:

/**
 * Changes the detail fragment of this activity. This is how all content is presented in this app.
 * @param fragment
 * @param animated
 * @param addCurrentFragmentToBackStack
 */
private void changeDetailFragment(Fragment fragment,boolean animated,boolean addCurrentFragmentToBackStack)
{
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

        if (animated)
            transaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);

    Fragment currentFrag =  getSupportFragmentManager().findFragmentById(R.id.detailFragment);


    String fragName = "NONE";

    if (currentFrag!=null)
        fragName = currentFrag.getClass().getSimpleName();


    if (currentFrag != null)
    {

        transaction.remove(currentFrag);
    }


    transaction.add(R.id.detailFragment,fragment);


    if (addCurrentFragmentToBackStack)
    {
        Log.i("APP_NAME","Adding: " + fragName + " to the backstack");
        transaction.addToBackStack(null);
    }
    else
    {
        Log.i("APP_NAME","Not adding: " + fragName + " to the backstack");
    }



    transaction.commit();

}

Hope this helps.



回答3:

For me changing the version of appcompat to 27.1.1(As of 15/08/2018) worked. Turns out appcompat version v7:28.0.0-rc01 was the culprit.