Today’s #AndroidDev #protip from +Nick Butcher is about correctly creating fragments.

Fragments are a great way of decomposing your application into reusable components and helping you create flexible layouts.  When creating your own fragments, you may be tempted to supply initialisation data through an overloaded constructor, to practice good encapsulation.  Doing so, however, would be a mistake as fragment instances can be re-created as part of the containing activity’s lifecycle.  Fragment’s javadoc [0] explains:

“Every fragment must have an empty constructor, so it can be instantiated when restoring its activity's state. It is strongly recommended that subclasses do not have other constructors with parameters, since these constructors will not be called when the fragment is re-instantiated…”

A pattern for encapsulating data needed to initialise a fragment is to offer a static creator method, commonly named newInstance.  This creates the fragment and stashes data in the arguments bundle which is persisted over re-creations:

public static class MyFragment extends Fragment {

  public MyFragment() { }  // Required empty constructor

  public static MyFragment newInstance(String foo, int bar) {
    MyFragment f = new MyFragment();
    Bundle args = new Bundle();
    args.putString(ARG_FOO, foo);
    args.putInt(ARG_BAR, bar);
    f.setArguments(args);
    return f;
  }

You can then access this data at a later point:

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  Bundle args = getArguments();
  if (args != null) {
    // Use initialisation data
  }
}

This pattern allows you to encapsulate the arguments that your fragment needs to initialise while playing nicely with the lifecycle methods.  If you have other tips for working with fragments then let us know in the comments.

[0] https://developer.android.com/reference/android/app/Fragment.html#Fragment()
Shared publiclyView activity