Search code examples
javaandroidspinner

How to show my spinner within one fragment


I am on creating an application and at the moment, I have created two fragments which is going to be a "navigation" sort of thing. On the second of the two fragments, I have put a spinner on which is where the user would be able to select a particular option. All of the spinners have unique ID's but the findViewById method cannot be resolved

All of the strings are in the strings xml file and when I tried this spinner in my testing app, it worked

public class Frag2 extends Fragment implements AdapterView.OnItemSelectedListener{

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.frag2_layout, container, false);

        Spinner spinner = findViewById (R.id.spinner1);
        ArrayAdapter.createFromResource(getActivity(), R.array.insulin, android.R.layout.simple_spinner_item);
        ArrayAdapter<CharSequence> adapter;
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);
        spinner.setOnItemSelectedListener(this);
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        String text = parent.getItemAtPosition(position).toString();
        Toast.makeText(parent.getContext(), text, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }
}

The spinner should work within the one fragment and then I would like to have it another few times


Solution

  • This is fragment you're dealing with, not an activity. Fragment doesn't extend Context or View classes and does not have this findViewById method.

    What you should do is to move your code from onCreateView to onViewCreated which gets a reference to the root view as a parameter. Then use the same method but with that view, as below:

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        Spinner spinner = view.findViewById(R.id.spinner1);
        ...
    }
    


    Another thing you may do is replacing:

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.frag2_layout, container, false);
    
        Spinner spinner = findViewById (R.id.spinner1);
        // I'm not sure how you didn't see all errors when writing code after a return statement.
    
        ...
    }
    

    With:

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.frag2_layout, container, false);
    
        Spinner spinner = view.findViewById(R.id.spinner1);
        ...
    
        return view; // after finishing all logic.
    }
    

    UPDATE:

    Didn't see that there is also a problem with the ArrayAdapter.
    As mentioned in Csongi77 answer, you need to to instantiate the adapter properly. Again, the fragment cannot use as context, you must use the containing activity for that:

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

    ArrayAdapter.createFromResource creates and returns a new adapter and currently you just disposing it immediately by not saving its reference.