One of the few eye openers for new application developers dealing with Fragments is as to how they are initialized. The recommended approach to use Fragment.setArguments might seem a bit too much of a work specially when the constructor is available. Besides, it seems to be error prone too as it could result in a fragment in an uninitialized state. This is even more so obvious for library developers exposing Fragments and application developers missing the prerequisites to use the Fragment (as its not a compile time enforcement). So why would anyone want setArguments? Its easy to adopt an approach once the reasoning is understood.
Although, both approach satisfy the initialization requirement, the deal breaker is a use case of orientation change when the activity for most applications is recreated (as long as the developers aren't handling it via onConfigurationChange). In this case, the activity is destroyed and a new instance of the activity is created and this also implies that the fragments hosted in the activity too would have to be created again. This part of the activity and fragment creation is automated by the framework and is abstracted to the application developers. In this case, its trivial for the framework to set arguments on the user specified Fragment instance rather than dealing with empty and non-empty constructors.
It does this by saving the fragment info in FragmentState,
final class FragmentState implements Parcelable {
final String mClassName;
final int mIndex;
final boolean mFromLayout;
final int mFragmentId;
final int mContainerId;
final String mTag;
final boolean mRetainInstance;
final boolean mDetached;
final Bundle mArguments;
...
}
and using mArguments to create the new fragment instance
Fragment f = (Fragment)clazz.newInstance();
if (args != null) {
args.setClassLoader(f.getClass().getClassLoader());
f.mArguments = args;
}
However, this is needed only in activities which let themselves to be recreated upon orientation change. If developers choose to have just one instance of the activity, then it really doesn't matter as to how the fragments are initialized. However, as Fragments are supposed to be reusable UI elements, it is safer to initialize via setArguments() to handle all use cases.
Although, both approach satisfy the initialization requirement, the deal breaker is a use case of orientation change when the activity for most applications is recreated (as long as the developers aren't handling it via onConfigurationChange). In this case, the activity is destroyed and a new instance of the activity is created and this also implies that the fragments hosted in the activity too would have to be created again. This part of the activity and fragment creation is automated by the framework and is abstracted to the application developers. In this case, its trivial for the framework to set arguments on the user specified Fragment instance rather than dealing with empty and non-empty constructors.
It does this by saving the fragment info in FragmentState,
final class FragmentState implements Parcelable {
final String mClassName;
final int mIndex;
final boolean mFromLayout;
final int mFragmentId;
final int mContainerId;
final String mTag;
final boolean mRetainInstance;
final boolean mDetached;
final Bundle mArguments;
...
}
and using mArguments to create the new fragment instance
Fragment f = (Fragment)clazz.newInstance();
if (args != null) {
args.setClassLoader(f.getClass().getClassLoader());
f.mArguments = args;
}
However, this is needed only in activities which let themselves to be recreated upon orientation change. If developers choose to have just one instance of the activity, then it really doesn't matter as to how the fragments are initialized. However, as Fragments are supposed to be reusable UI elements, it is safer to initialize via setArguments() to handle all use cases.
No comments:
Post a Comment