简体   繁体   中英

Spinner value not being correctly set

I am trying to set a spinner value that has been passed from another Fragment. This spinner is populated with data from a LiveModel and I want just set the index of the spinner to the String value passed.

Currently the code below gives me the default value of the spinner as the line below returns -1;

spinner.setSelection(adapter.getPosition(holidaySelected));

Can anyone see why this is returning -1 and not the position of the adapter at which the value sits?

I have read this thread: How to set selected item of Spinner by value, not by position?

public class PlaceInputFragment extends Fragment {

private String holidaySelected;
private HolidayViewModel holidayViewModel;
private List<String> holidayNames;
private Spinner spinner;
private ArrayAdapter<String> adapter;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    holidayNames = new ArrayList<>();
    spinner = v.findViewById(R.id.spinner);
    adapter = new ArrayAdapter<>(getContext(), android.R.layout.simple_spinner_item, holidayNames);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);

    holidayViewModel = ViewModelProviders.of(this).get(HolidayViewModel.class);
    holidayViewModel.getAllHolidays().observe(this, new Observer<List<Holiday>>() {
        @Override
        public void onChanged(@Nullable final List<Holiday> holidays) {
            for (Holiday holiday : holidays) {
                holidayNames.add(holiday.getName());
            }
            adapter.notifyDataSetChanged();
        }
    });
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    if (getArguments() != null) {
    spinner = v.findViewById(R.id.spinner);

        holidaySelected = getArguments().getString("Holiday");
        spinner.setSelection(adapter.getPosition(holidaySelected));
    }
}

The issue I was having is caused by the fact that in onViewCreated when I was wanting to set the selected item in the spinner, the observer you set up to get the list of holiday names which populates the spinner with values has not yet returned. I forgot that this runs in another thread in the background. The result is that the spinner is still empty at this point. The log statement below confirmed this

Log.i(TAG, "Size of name list is " + holidayNames.size());

The fix that I worked with was: Create a new field for the PlaceInputFragment

private String holidayName;

In onCreateView set its value BEFORE doing anything to initialise the spinner.

if (getArguments() != null) {
            holidayName = getArguments().getString("Holiday");
} else {
            holidayName = null;
}

Finally in the observer for getAllHolidays, AFTER the line adapter.notifyDataSetChanged(); I put the following:

if (holidayName != null) {
    int i = holidayNames.indexOf(holidayName);
    spinner.setSelection(i);
}

ANOTHER way to do it would be to use safeArgs:

Set holidayName in onViewCreated:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    if (getArguments() != null) {
PhotoInputFragmentArgs args PhotoInputFragmentArgs.fromBundle(getArguments());
holidayName = photo.getHolidayName();
}

Then, in the observer for getAllHolidays, AFTER the line adapter.notifyDataSetChanged(); put the following:

if (holidayName != null) {
    int i = holidayNames.indexOf(holidayName);
    spinner.setSelection(i);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM