androidfindviewbyid

How do I use findViewById to get a ViewGroup outside OnCreateView in a Fragment?


I have a ConstraintLayout (the child) nested in another ConstraintLayout (the parent). I want to be able to call the child from within my Fragment class, but outside onCreateView. This what I have so far:

public class HomeFragment extends Fragment {

    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        HomeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);
        View root = inflater.inflate(R.layout.fragment_home, container, false);

        return root;
    }

    ConstraintLayout MyLayout = (ConstraintLayout) getView().findViewById(R.id.my_layout);
}

Which results in a NullPointerException:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference

I even tried declaring a global root variable in the Fragment class and assigning the inflated view result to it, but the problem persists.

I cannot place myLayout inside OnCreateView so I need a solution where I can use it outside of it.


Solution

  • Your issue stems from a misunderstanding about when and for how long a fragment's view exists.

    Currently, you are assigning your MyLayout variable during construction of your fragment.

    According to the Android documentation on a Fragment's lifecycle a fragment won't have a view associated with it until after onCreateView is called. Later on in the fragment's lifecycle, the view is destroyed when onDestroyView is called.

    So, the fragment's view only lives during the intervening time between onCreateView and onDestroyView. If you call getView before onCreateView is called, or after onDestroyView is called, you will get null.

    So, if you want to set listeners on views, do so either from onCreateView or onViewCreated and remove them in onDestroyView.

    Also, if you want to hold onto your view via a member variable, set it in onCreateView and null it out in onDestroyView and any place you reference it, make sure to check for null first.