Search code examples
androidlifecyclefragment

Problems with Fragment lifecycle and onCreate being called on non existent fragment


I am testing fragments in Android and I'm having some confusing behavior with Fragment life cycle. I have a activity that uses layouts in xml for both landscape and portrait modes. I have some code that accesses a EditText object that is defined in one of the fragment layouts. If I start the app in landscape mode things work. I access the component in the onResume() fragment method to update some text.

According to the documentation the onResume() fragment method is called when the fragment is visible to the user. However, if I rotate the screen this method gets called again even though this fragment is not defined in the portrait layout. This call to onCreate causes a NullPointerException becuase this method references the EditText object. Why is onResume method called on a fragment that is not part of the new layout? How and where is the proper place to modify layout data in a fragment. I have tried onStart, onResume, onActivityCreated etc, but all seem to return the same error.

Any help would be most appreciated.


Solution

  • When you rotate the screen, Android saves your fragments in a Bundle and recreates them when it recreates the activity. That is why you get calls to a non-existing (actually just invisible) fragment. You need to handle this situation in the fragment code, or simply have both fragments in the land and port layouts, where you set the fragment visibility to GONE if you don't need it.

    A simple way to check if the fragment is visible in code is this:

     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            if (container == null) {
                return null;
            }
      }
    

    If container is null, your fragment is being re-created from a Bundle and won't be shown (since there is no container). You then have to check whether getView() is null and short-circuit your code accordingly. This can get messy though, so beware :)