Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice for instantiating a new Android Fragment

I have seen two general practices to instantiate a new Fragment in an application:

Fragment newFragment = new MyFragment(); 

and

Fragment newFragment = MyFragment.newInstance(); 

The second option makes use of a static method newInstance() and generally contains the following method.

public static Fragment newInstance()  {     MyFragment myFragment = new MyFragment();     return myFragment; } 

At first, I thought the main benefit was the fact that I could overload the newInstance() method to give flexibility when creating new instances of a Fragment - but I could also do this by creating an overloaded constructor for the Fragment.

Did I miss something?

What are the benefits of one approach over the other? Or is it just good practice?

like image 769
Graham Smith Avatar asked Feb 12 '12 00:02

Graham Smith


People also ask

How do you instantiate a fragment?

The correct way to instantiate a new fragment and passing values to it, is by creating a bundle, setting arguments on this bundle and then passing it to our fragment. Inside the fragment we then retrieve this bundle and get the values out of it. A clean way to do this is by creating a so called “factory method”.

Why is it recommended to use only the default constructor to create a fragment?

Traditionally, a Fragment instance could only be instantiated using its default empty constructor. This is because the system would need to reinitialize it under certain circumstances like configuration changes and the app's process recreation.

Are fragments faster than activities?

I do find fragments a slightly faster than activities but really its not something you would really notice in most cases. Regardless if they was intended for speed or not they still seem/feel little quicker. The downside of using fragments, is certain callbacks like onBackPressed is only in an activity.


2 Answers

If Android decides to recreate your Fragment later, it's going to call the no-argument constructor of your fragment. So overloading the constructor is not a solution.

With that being said, the way to pass stuff to your Fragment so that they are available after a Fragment is recreated by Android is to pass a bundle to the setArguments method.

So, for example, if we wanted to pass an integer to the fragment we would use something like:

public static MyFragment newInstance(int someInt) {     MyFragment myFragment = new MyFragment();      Bundle args = new Bundle();     args.putInt("someInt", someInt);     myFragment.setArguments(args);      return myFragment; } 

And later in the Fragment onCreate() you can access that integer by using:

getArguments().getInt("someInt", 0); 

This Bundle will be available even if the Fragment is somehow recreated by Android.

Also note: setArguments can only be called before the Fragment is attached to the Activity.

This approach is also documented in the android developer reference: https://developer.android.com/reference/android/app/Fragment.html

like image 192
yydl Avatar answered Sep 20 '22 19:09

yydl


The only benefit in using the newInstance() that I see are the following:

  1. You will have a single place where all the arguments used by the fragment could be bundled up and you don't have to write the code below everytime you instantiate a fragment.

    Bundle args = new Bundle(); args.putInt("someInt", someInt); args.putString("someString", someString); // Put any other arguments myFragment.setArguments(args); 
  2. Its a good way to tell other classes what arguments it expects to work faithfully(though you should be able to handle cases if no arguments are bundled in the fragment instance).

So, my take is that using a static newInstance() to instantiate a fragment is a good practice.

like image 24
500865 Avatar answered Sep 23 '22 19:09

500865