Search code examples
androidandroid-fragmentsserializable

Argument in Fragment null in onCreateView


Within my Activity I begin the FragmentTransaction and set an Argument to my Fragment.

DetailFragment detailFragment = new DetailFragment();
Bundle bundle = new Bundle();
bundle.putSerializable(Constants.KEY_PRODUCT, navigate.product);
detailFragment.setArguments(bundle);

Within my Fragments class I override the setArgument method and parse the Serializable object:

Product product;

@Override
public void setArguments(Bundle args) {
    super.setArguments(args);

    product = (Product) args.getSerializable(Constants.KEY_PRODUCT);
}

All of this is working fine, but as soon as I am debugging within my onCreateView() method, the previously set product is null. Can somebody explain this to me? And what is the correct approach to do this?

EDIT:

Following the answer by Michael I ended up with the following pieces of code: In the Activity:

DetailFragment detailFragment = DetailFragment.newInstance(navigate.product);

And in the Fragment:

 public static DetailFragment newInstance(Product product) {
        DetailFragment fragment = new DetailFragment();
        Bundle args = new Bundle();
        args.putSerializable(Constants.KEY_PRODUCT, product);
        fragment.setArguments(args);
        return fragment;
    }

But when I try to access the getArgument() within onCreate() it will give null:

if (getArguments() != null) {
     product = (Product) getArguments().getSerializable(Constants.KEY_PRODUCT);
}

and my Product is never set. Did I miss something else?


Solution

  • You should call getArguments in onCreate.

    If you look at the generated code when adding a new fragment to your project in Android Studio:

    public class BlankFragment extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";
    
    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;
    
    
    public BlankFragment() {
        // Required empty public constructor
    }
    
    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment BlankFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static BlankFragment newInstance(String param1, String param2) {
        BlankFragment fragment = new BlankFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_blank, container, false);
    }
    
    }
    

    The arguments are set in the fragments constructor and are pulled back out in onCreate since onCreate is called befre onCreateView in the fragment lifecycle you will be able to access these arguments in onCreateView and later.