Dabbler
Dabbler

Reputation: 9863

Understanding the Fragment.newInstance method

I'm implementing an Android fragment. I understand that the framework can automatically destroy and recreate the fragment, and that recreating a fragment calls its default constructor, as opposed to a constructor that has arguments. There are many posts (such as the accepted answer to this question) that show how to provide arguments to the fragment by implementing a static newInstance method.

What I don't understand is who calls newInstance. My first impression was that - since one can define arbitrary arguments for this newInstance method - I should add an explicit call to it somewhere in the app, and that the name newInstance is just a naming convention. But then I would be creating a second fragment in addition to the one created by framework calling the default constructor, which confuses me.

So is the above assumption incorrect, and the newInstance method is really somehow an overload of Java's built-in method for instantiating a class? In that case, I don't see how I can define a newinstance method that takes an arbitrary argument list. Or is that possible in Java, and I just don't know Java well enough?

Upvotes: 7

Views: 17459

Answers (3)

HenryHaoson
HenryHaoson

Reputation: 31

Fragment.newInstance(args1,args2...) is used as static construction method. The benefits of static construction method is Needless to say. But in Fragment, doing this can help us to save arguments, and we can get these arguments in onCreate() Method for when accidentally your app boom,and Android help you to restore your fragment with Constructor without arguments.

public static StudyFragment newInstance(ArrayList<DailyWordBean.DataBean> list) {
    Bundle args = new Bundle();
    args.putSerializable("data", list);
    StudyFragment fragment = new StudyFragment();
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        list = (ArrayList<DailyWordBean.DataBean>) getArguments().getSerializable("data");
        Log.e("study", list.size() + list.get(0).getWordContent());
    }
}

Remember to use Parcelable instead of Serializable.

Upvotes: 3

royB
royB

Reputation: 12977

newInstance is an Android design pattern because of the fact that Fragment Should not have any other Constructor beside the default Constructor

Thus you define an Helper function in order to pass Arguments to the Fragment

You don't have to use it but Let's say you have 2 Activities that both starts FragmentA

If you will not Use the helper function You will need to duplicate the code to instantiate the Fragment.

What I don't understand is who calls newInstance

Usually you will use the instantiate method from places that creates Fragments...Activity, Adapter and such.

SectionPagerAdapter example:

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).
        return PlaceholderFragment.newInstance(position + 1);
    }

Where PlaceholderFragment.newInstance(int position) is

public static PlaceholderFragment newInstance(int sectionNumber) {
        PlaceholderFragment fragment = new PlaceholderFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        fragment.setArguments(args);
        return fragment;
    }

In that case, I don't see how I can define a newinstance method that takes an arbitrary argument list.

You can pass arbitrary argument list but you need to know the value Type because Bundle has only putX() methods, where X is the type of the parameter

Upvotes: 7

Arkadiusz Konior
Arkadiusz Konior

Reputation: 1159

You can name the function however you like: newInstance, getInstance, newFragment. It doesn't matter, it is only a helper method. Important is that you put all your arguments with fragment.setArguments(args). Android system will remember those arguments and will use them when fragment will be recreated.

public static MyFragment newInstance(int arg) {

    Bundle args = new Bundle();
    args.putInt("ARG", arg);

    MyFragment fragment = new MyFragment();
    fragment.setArguments(args);
    return fragment;
}

Upvotes: 12

Related Questions