I am creating an app with Fragments
and in one of them, I created a non-default constructor and got this warning:
Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead
Can someone tell me why this is not a good idea?
Can you also suggest how I would accomplish this:
public static class MenuFragment extends ListFragment {
public ListView listView1;
Categories category;
//this is my "non-default" constructor
public MenuFragment(Categories category){
this.category = category;
}....
Without using the non-default constructor?
If you use parameter for some class. try this
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.
Your
Fragment
shouldn't have constructors because of how theFragmentManager
instantiates it. You should have anewInstance()
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 theBundle
parameter.For example:
And read these arguments at
onCreate
:This way, if detached and re-attached, the object state can be stored through the arguments, much like
bundles
attached toIntent
s.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 yourbundle
.The callbacks like
onCreate
oronCreateView
should read the parameters from thebundle
- this way you are guaranteed to restore the state of thefragment
correctly to the same state thefragment
was initialised with (note this state can be different from theonSaveInstanceState bundle
that is passed to theonCreate/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 thebundle
inside the body of that constructor. And read those parameters in theonCreate()
oronCreateView()
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:After that, in your fragment access data:
That's all.