MarshallLee
MarshallLee

Reputation: 1330

IndexOutOfBoundException on Android Spinner

I'm making an application which converts units into different ones. I am trying to make the app work in the following step.

  1. choose a category with a spinner (temperature, length, etc.)
  2. depending on which category to choose, the other two spinners will be showing units that belong to each category.

Here's the code so far.

public class UnitConverterFragment extends Fragment implements AdapterView.OnItemSelectedListener {
    private EditText etValue;
    private Spinner spCategory, spFrom, spTo;
    private UnitConverter currentConverter, lastConverter;
    private ArrayAdapter<String> categoryArrayAdapter;
    private ArrayAdapter<CharSequence> unitArrayAdapter;
    private String unitFrom, unitTo;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_unitconverter, container, false);
        spCategory = (Spinner) view.findViewById(R.id.spCategory);
        spFrom = (Spinner) view.findViewById(R.id.spFrom);
        spTo = (Spinner) view.findViewById(R.id.spTo);
        etValue = (EditText) view.findViewById(R.id.etValue);

        spCategory.setOnItemSelectedListener(this);
        spFrom.setOnItemSelectedListener(this);
        spTo.setOnItemSelectedListener(this);

        categoryArrayAdapter = new ArrayAdapter<>(view.getContext(), android.R.layout.simple_spinner_dropdown_item, getResources().getStringArray(R.array.category));
        categoryArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spCategory.setAdapter(categoryArrayAdapter);
        categoryArrayAdapter.setNotifyOnChange(true);

        unitArrayAdapter = new ArrayAdapter<>(view.getContext(), android.R.layout.simple_spinner_item);
        unitArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spFrom.setAdapter(unitArrayAdapter);
        spTo.setAdapter(unitArrayAdapter);

        unitArrayAdapter.setNotifyOnChange(true);

        currentConverter = new TemperatureConverter();
        lastConverter = currentConverter;

        return view;
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

        if(view.getParent() == spCategory) {
            switch(position) {
                case 0:
                    setConverter(new TemperatureConverter());
                    break;
                case 1:
                    setConverter(new LengthConverter());
                    break;
                case 2:
                    setConverter(new MassConverter());
                    break;
                case 3:
                    setConverter(new SpeedConverter());
                    break;
                case 4:
                    setConverter(new VolumeConverter());
                    break;
                case 5:
                    setConverter(new AreaConverter());
                    break;
                case 6:
                    setConverter(new FuelConsumptionConverter());
                    break;
                case 7:
                    setConverter(new TimeConverter());
                    break;
                case 8:
                    setConverter(new DigitalStorageConverter());
                    break;
            }

            fillFromToSpinner(position);

            spFrom.setSelection(0);
            spTo.setSelection(0);

            **unitFrom = spFrom.getItemAtPosition(0).toString();
            unitTo = spTo.getItemAtPosition(0).toString();**

        } else if(view.getParent() == spFrom) {
            unitFrom = spFrom.getSelectedItem().toString();
        } else if(view.getParent() == spTo) {
            unitTo = spTo.getSelectedItem().toString();
        }
    }

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

    }

    private void setConverter(UnitConverter converter) {
        lastConverter = currentConverter;
        currentConverter = converter;

        lastConverter = null;
    }

    private void fillFromToSpinner(int position) {
        switch(position) {
            case 0:
                fillSpinnerWithTemperatureUnits();
                break;
            case 1:
                fillSpinnerWithLengthUnits();
                break;
            case 2:
                fillSpinnerWithMassUnits();
                break;
            case 3:
                fillSpinnerWithSpeedUnits();
                break;
            case 4:
                fillSpinnerWithVolumeUnits();
                break;
            case 5:
                fillSpinnerWithAreaUnits();
                break;
            case 6:
                fillSpinnerWithFuelConsumptionUnits();
                break;
            case 7:
                fillSpinnerWithTimeUnits();
                break;
            case 8:
                fillSpinnerWithDigitalStorageUnits();
                break;
        }
    }

    private void fillSpinnerWithTemperatureUnits() {
        unitArrayAdapter.clear();
        unitArrayAdapter.createFromResource(getView().getContext(), R.array.temperature, android.R.layout.simple_spinner_item);
        unitArrayAdapter.notifyDataSetChanged();
    }

    private void fillSpinnerWithLengthUnits() {
        unitArrayAdapter.clear();
        unitArrayAdapter.createFromResource(getView().getContext(), R.array.length, android.R.layout.simple_spinner_item);
        unitArrayAdapter.notifyDataSetChanged();
    }

    private void fillSpinnerWithMassUnits() {
        unitArrayAdapter.clear();
        unitArrayAdapter.createFromResource(getView().getContext(), R.array.mass, android.R.layout.simple_spinner_item);
        unitArrayAdapter.notifyDataSetChanged();

    }

    private void fillSpinnerWithSpeedUnits() {
        unitArrayAdapter.clear();
        unitArrayAdapter.createFromResource(getView().getContext(), R.array.speed, android.R.layout.simple_spinner_item);
        unitArrayAdapter.notifyDataSetChanged();
    }

    private void fillSpinnerWithVolumeUnits() {
        unitArrayAdapter.clear();
        unitArrayAdapter.createFromResource(getView().getContext(), R.array.volume, android.R.layout.simple_spinner_item);
        unitArrayAdapter.notifyDataSetChanged();
    }

    private void fillSpinnerWithAreaUnits() {
        unitArrayAdapter.clear();
        unitArrayAdapter.createFromResource(getView().getContext(), R.array.area, android.R.layout.simple_spinner_item);
        unitArrayAdapter.notifyDataSetChanged();
    }

    private void fillSpinnerWithFuelConsumptionUnits() {
        unitArrayAdapter.clear();
        unitArrayAdapter.createFromResource(getView().getContext(), R.array.fuel_consumption, android.R.layout.simple_spinner_item);
        unitArrayAdapter.notifyDataSetChanged();
    }

    private void fillSpinnerWithTimeUnits() {
        unitArrayAdapter.clear();
        unitArrayAdapter.createFromResource(getView().getContext(), R.array.time, android.R.layout.simple_spinner_item);
        unitArrayAdapter.notifyDataSetChanged();
    }

    private void fillSpinnerWithDigitalStorageUnits() {
        unitArrayAdapter.clear();
        unitArrayAdapter.createFromResource(getView().getContext(), R.array.digital_storage, android.R.layout.simple_spinner_item);
        unitArrayAdapter.notifyDataSetChanged();
    }
}

When running the app, it suddenly dies showing the IndexOutOfBoundException at the highlighted part.

FYI, here's the log.

java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
            at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
            at java.util.ArrayList.get(ArrayList.java:308)
            at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:337)
            at android.widget.AdapterView.getItemAtPosition(AdapterView.java:831)
            at com.marshall.calculator.ui.UnitConverterFragment.onItemSelected(UnitConverterFragment.java:102)
            at android.widget.AdapterView.fireOnSelected(AdapterView.java:964)
            at android.widget.AdapterView.access$200(AdapterView.java:49)
            at android.widget.AdapterView$SelectionNotifier.run(AdapterView.java:928)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:146)
            at android.app.ActivityThread.main(ActivityThread.java:5602)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
            at dalvik.system.NativeStart.main(Native Method)

Any suggestions for fixing this problem will be very much appreciated.

Upvotes: 0

Views: 157

Answers (2)

Want2bExpert
Want2bExpert

Reputation: 527

As suggested by others, unitArrayAdapter is empty. So what values do you want to pass to? If you compare your two adapters, you will see categoryArrayAdapter is populated with String[] while unitArrayAdapter is null.

Upvotes: 0

Sanjeev
Sanjeev

Reputation: 4375

Updated in your unitArrayAdapter you haven't passed any array string it is null , change it to this

private static final String[] items={"lorem", "ipsum", "dolor","sit", "amet","consectetuer", };

unitArrayAdapter = new ArrayAdapter<>(view.getContext(), android.R.layout.simple_spinner_item, items);

Upvotes: 2

Related Questions