Refresh fragment not working any more

2019-02-18 01:50发布

问题:

I lost some hours today because my functionaly code were not working any more. The code to reload the view of a fragment was not working anymore after updating to the new version of Support Library 25.1.0:

This is my code :

FragmentManager manager = getActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = manager.beginTransaction();
fragmentTransaction.detach(fragment);
fragmentTransaction.attach(fragment);
fragmentTransaction.commit();

I have tried to debug putting some breakpoints on

public void onPause()
public void onStop()
public void onAttach(Context context)
public void onDetach()  
public void onDestroyView()
public void onDestroy()

but the application is not entering into any of that function and nothing happened on the screen.

If I call detach alone, without attach, the application enter in onPause and onStop and the view leave the screen.

回答1:

I've found myself facing the same issue, and found no answer online. Finally I've found out that some optimizations were added to Fragment Transactions in Revision 25.1.1 of the Support Library. (see https://developer.android.com/topic/libraries/support-library/revisions.html#25-1-1). Disabling those for your transaction will make it work as expected:

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.setAllowOptimization(false);
transaction.detach(fragment).attach(fragment).commitAllowingStateLoss();

Update

setAllowOptimization is deprecated. Use setReorderingAllowed instead.



回答2:

Thanks so much for that. Here is a slight modification I made to use getSupportFragmentManager

FragmentTransaction t = getActivity().getSupportFragmentManager().beginTransaction();
t.setAllowOptimization(false);
t.detach(this).attach(this).commitAllowingStateLoss();


回答3:

@Viad actually answered the question. To add a little bit to it, this happens in android versions 26 and above where reordering is allowed by default. Reordering comes into play when two fragment operations are requested at the same done, for example adding fragment 1 and then replacing it with fragment 2, which causes only the latter (replacing fragment 2) to happen.

So when reordering is allowed by default, when restarting the fragment using detach(fragment).attach(fragment) the first one is ignored and only second one is executed. As the fragment is already attached, attach(fragment) does not do anything. This is why none of the lifecycle methods of the fragment is called.

The resolution to the problem would be to setReorderingAllowed(false) to deactivate reordering. So the solution would be:

                    FragmentTransaction transaction = mActivity.getFragmentManager()
                            .beginTransaction();
                    if (Build.VERSION.SDK_INT >= 26) {
                        transaction.setReorderingAllowed(false);
                    }
                    transaction.detach(fragment).attach
                            (fragment).commit();