Dimitrov V Dimitrov V - 6 months ago 13
Java Question

Load spinner with with objects and strings

This is my

Spinner
code that loads employee names from my SQL db as objects and displays them on screen:

private void loadNames() {
//database handler
LysandrosDatabaseAdapter db = new LysandrosDatabaseAdapter(getApplicationContext());

List<DataBean> list = db.getAllDat();

//list for storing the names
String[] nameList = new String[list.size()];
//list for storing the ID and keeping it hidden
employeeList = new int[list.size()];
//loop to fill the list

nameList[0] = "All Employees";
employeeList[0] = 0;
for (int i=0; i<list.size(); i++) {
nameList[i+1] = list.get(i).getName() + " " + list.get(i).getSurname();
employeeList[i+1] = list.get(i).getID();
}
//creating adapter for spinner
ArrayAdapter<String > dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, nameList);
//drop down layout style - list view with radio button
dataAdapter.setDropDownViewResource(android.R.layout.select_dialog_multichoice);
//attaching data adapter to spinner
selectName.setAdapter(dataAdapter);
}


I'm trying to include a text reading "All Employees" as the first option because I want to implement an
If
statement that when users select the option "All Employees" the app will fetch some particular data and when users select a specific employee, e.g. "John Smith" the app will fetch data only for that record.

The snippet above is what I've come to so far and I'm getting an
ArrayIndexOutOfBoundsException
error.

My LogCat shows this:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.lysandroslysandrou.marstest4/com.example.lysandroslysandrou.marstest4.Reports}: java.lang.ArrayIndexOutOfBoundsException: length=5; index=5
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.ArrayIndexOutOfBoundsException: length=5; index=5
at com.example.lysandroslysandrou.marstest4.Reports.loadNames(Reports.java:147)
at com.example.lysandroslysandrou.marstest4.Reports.onCreate(Reports.java:78)


Line 147 is
nameList[i+1] = list.get(i).getName() + " " + list.get(i).getSurname();


I've tried many other methods but none of them worked. Loading a value saved as "All Employees" from my db is also not a viable solution.

I'm looking for two things:

A) Why am I getting this error particularly in my case? (I've read about this exception here and here but can't understand why it's happening here)

and B) Is there a solution to my problem?

NOTE: If lines
nameList[0] = "All Employees
and
employeeList[0] = "0"
are removed the snippet works fine.

EDIT: My new stack trace:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:394)
at android.widget.ArrayAdapter.getDropDownView(ArrayAdapter.java:415)
at android.support.v7.widget.AppCompatSpinner$DropDownAdapter.getDropDownView(AppCompatSpinner.java:624)
at android.support.v7.widget.AppCompatSpinner$DropDownAdapter.getView(AppCompatSpinner.java:620)
at android.support.v7.widget.AppCompatSpinner.compatMeasureContentWidth(AppCompatSpinner.java:547)
at android.support.v7.widget.AppCompatSpinner.access$500(AppCompatSpinner.java:65)
at android.support.v7.widget.AppCompatSpinner$DropdownPopup.computeContentWidth(AppCompatSpinner.java:738)
at android.support.v7.widget.AppCompatSpinner$DropdownPopup.show(AppCompatSpinner.java:763)
at android.support.v7.widget.AppCompatSpinner.performClick(AppCompatSpinner.java:424)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)


EDIT 2: This is my
onItemSelected
method:

@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
//On selecting a spinner item
String list = parent.getItemAtPosition(position).toString();
//employeeId = employeeList[position];
//showing selected spinner item
Toast.makeText(parent.getContext(), "You selected: " + list, Toast.LENGTH_SHORT).show();
}

Answer

You need to change

//list for storing the names
String[] nameList = new String[list.size()];
//list for storing the ID and keeping it hidden
employeeList = new int[list.size()];

to

//list for storing the names
String[] nameList = new String[list.size() + 1];
//list for storing the ID and keeping it hidden
employeeList = new int[list.size() + 1];

because you need to allocate one more item for the first "All employees" element.

And you're getting an ex—Āeption when try to access namesList[i + 1] element, when i == list.size() - 1, so i + 1 == list.size(). For example, access namesList[5], when you've allocated only 0..4 elements with String[] nameList = new String[list.size()];

I commented some lines, because I doesn't have you db. But the follwing code works fine for me:

private void loadSpinner(Spinner spinner, ArrayList<Integer> items) {
    //list for storing the names
    String[] nameList = new String[items.size() + 1];
    //list for storing the ID and keeping it hidden
    //employeeList = new int[list.size()];
    //loop to fill the list

    nameList[0] = "All Employees";
    //employeeList[0] = 0;
    for (int i = 0; i < items.size(); i++) {
        nameList[i + 1] = String.valueOf(i);
    }
    //creating adapter for spinner
    ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, nameList);
    //drop down layout style - list view with radio button
    dataAdapter.setDropDownViewResource(android.R.layout.select_dialog_multichoice);
    //attaching data adapter to spinner
    spinner.setAdapter(dataAdapter);
}