Reputation: 9863
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
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
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
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