Search code examples
androidandroid-fragmentsandroid-spinner

How do I create a spinner in a fragment layout?


I am following Google's spinner example to create a simple Spinner in a Fragment. Here is what I have done so far:

fragment_home.xml

<Spinner
    android:id="@+id/spinner"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginTop="6dp"
    app:layout_constraintEnd_toEndOf="@+id/textView5"
    app:layout_constraintStart_toStartOf="@+id/textView5"
    app:layout_constraintTop_toBottomOf="@+id/textView5" />

HomeFragment.java

public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    ...
    Spinner spinner = (Spinner) getView().findViewById(R.id.spinner);
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getActivity(), R.array.spinner_options, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);
}

strings.xml

<resources>
    ...
    <string-array name="spinner_options">
        <item>Round-robin</item>
        <item>Double round-robin</item>
        <item>Swiss</item>
        <item>Knockout</item>
        <item>Team round-robin</item>
        <item>Team Swiss</item>
        <item>Team knockout</item>
        <item>Match</item>
    </string-array>
</resources>

When I try to build the app, I get an error:

error: incompatible types: HomeFragment cannot be converted to Context
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this
                                                                         ^

I read in this post that I have to pass the Activity as the first parameter instead of the fragment, so I tried replacing this with getActivity() and then with this.getActivity(). In both cases, the app builds successfully but does not run.

Am I doing anything wrong here? Can someone point out my mistake?


Solution

  • You are not supposed to use getView() in onCreateView as the fragment view is not created yet. because actually onCreateView returns its view to be created.

    So, the below line of code will cause NPE

    Spinner spinner = (Spinner) getView().findViewById(R.id.spinner);
    

    If you want to setup the spinner in onCreateView then you need to inflate the view first with

     View view = inflater.inflate(R.layout.my_fragment_layout, container, false);
     Spinner spinner = view.findViewById(R.id.spinner);
    

    You can use getView() for any fragment lifecycle method that comes after onCreateView like onViewCreated, onStart, or onResume

    Then as you mentioned use getActivity() or requireActivity() for building up the adapter

    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(requireActivity(), 
                                 R.array.spinner_options, 
                                 android.R.layout.simple_spinner_item);