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.
If not Java compiler provides a no-argument, default constructor on your behalf. This is a constructor initializes the variables of the class with their respective default values (i.e. null for objects, 0.0 for float and double, false for boolean, 0 for byte, short, int and, long).
Fragment Arguments The parameterless constructor is needed because the system cannot know how to call a constructor that accepts parameters.
Example 5: Default Constructor Hence, the Java compiler automatically creates the default constructor. The default constructor initializes any uninitialized instance variables with default values. In the above program, the variables a and b are initialized with default value 0 and false respectively.
It seems like none of the answers actually answer "why use bundle for passing parameters rather than non default constructors"
The reason why you should be passing parameters through bundle is because when the system restores a fragment
(e.g on config change), it will automatically restore your bundle
.
The callbacks like onCreate
or onCreateView
should read the parameters from the bundle
- this way you are guaranteed to restore the state of the fragment
correctly to the same state the fragment
was initialised with (note this state can be different from the onSaveInstanceState bundle
that is passed to the onCreate/onCreateView
)
The recommendation of using the static newInstance()
method is just a recommendation. You can use a non default constructor but make sure you populate the initialisation parameters in the bundle
inside the body of that constructor. And read those parameters in the onCreate()
or onCreateView()
methods.
Make a bundle object and insert your data (in this example your Category
object). Be careful, you can't pass this object directly into the bundle, unless it's serializable.
I think it's better to build your object in the fragment, and put only an id or something else into bundle. This is the code to create and attach a bundle:
Bundle args = new Bundle();
args.putLong("key", value);
yourFragment.setArguments(args);
After that, in your fragment access data:
Type value = getArguments().getType("key");
That's all.
Your Fragment
shouldn't have constructors because of how the FragmentManager
instantiates it.
You should have a newInstance()
static method defined with the parameters you need, then bundle them and set them as the arguments of the fragment, which you can later access with the Bundle
parameter.
For example:
public static MyFragment newInstance(int title, String message) {
MyFragment fragment = new MyFragment();
Bundle bundle = new Bundle(2);
bundle.putInt(EXTRA_TITLE, title);
bundle.putString(EXTRA_MESSAGE, message);
fragment.setArguments(bundle);
return fragment ;
}
And read these arguments at onCreate
:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
title = getArguments().getInt(EXTRA_TITLE);
message = getArguments().getString(EXTRA_MESSAGE);
//...
}
This way, if detached and re-attached, the object state can be stored through the arguments, much like bundles
attached to Intent
s.
If you use parameter for some class. try this
SomeClass mSomeInstance;
public static final MyFragment newInstance(SomeClass someInstance){
MyFragment f = new MyFragment();
f.mSomeInstance = someInstance;
return f;
}
I think, there is no difference between static constructor and two constructors (empty and parametrized one that stores arguments into a Fragment's arguments bundle), most probably, this rule of thumb is created to reduce probability of forgetting to implement no-arg constructor in Java, which is not implicitly generated when overload present.
In my projects I use Kotlin, and implement fragments with a primary no-arg constructor and secondary constructor for arguments which just stores them into a bundle and sets it as Fragment arguments, everything works fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With