Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android Android Fragments Introducing Fragments Keeping Track of Instance State

Benjamin McKenzie
Benjamin McKenzie
7,455 Points

findFragmentById

I don't understand why refactoring the fragment to be a field and using the savedInstanceState to tell if it needs to be added doesn't work. Why would we need to use findFragmentById()?

1 Answer

Boban Talevski
Boban Talevski
24,793 Points

Answering this over a year later, but maybe someone finds it useful as it made me rethink what Ben said as well.

The thing is, it's not that refactoring the fragment as a field wouldn't really work. We wouldn't have a new Fragment on every rotation if that's the only thing we need to fix, but that field will be null for the lifetime of the app after the first device rotation or press of the home button f.e. (or whatever causes the activity's onCreate method to be called for a second time).

So, in this case, the Activity will be recreated, savedInstanceState will not be null, so we won't assign any value to that fragment field and we'll end up with a null field for the rest of the app lifetime which makes it pretty much useless if we do need it as Ben says in other methods in MainActivity. That's why this "trick" with getting the savedFragment from the fragmentManager is the more appropriate solution for the problem.

We would also need to rename our fragment variable to match savedFragment (or maybe simply call it just fragment) and can then refactor the savedFragment to be a field and we will have access to the fragment at the starting point of the app and throughout all the rotations and home button presses, the fragment will be referred by the savedFragment field at all times.

This is my MainActivity.java implementing this solution:

public class MainActivity extends LoggingActivity implements ListFragment.OnRecipeSelectedInterface{

    private ListFragment savedFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        savedFragment = (ListFragment) getFragmentManager().findFragmentById(R.id.placeHolder);
        if (savedFragment == null) {
            savedFragment = new ListFragment();
            FragmentManager fragmentManager = getFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            fragmentTransaction.add(R.id.placeHolder, savedFragment);
            fragmentTransaction.commit();
        }
    }

    @Override
    public void onListRecipeSelected(int index) {
        Toast.makeText(this, Recipes.names[index], Toast.LENGTH_SHORT).show();
    }
}