Search code examples
javaandroidspinnerandroid-spinneronitemselectedlistener

Confused about onItemSelected parameters in android


I have a problem with understanding some concepts in Android. I don't quite get what the parent and the view specifically refer to in the onItemSelected method i have to define when creating a spinner with a listener (for example). I checked the documentation and tried a few examples, but it's not enough.

My main question comes from the following situation which i experimented with: I have a spinner, an array holding items A,B and C, and an array adapter to link them. In the onItemSelected method I log the ID of the parent and the view to see what happens.

No matter which items i select from the list (A, B or C) the output is the same: parent has an ID of W and view has an ID of X. I expected the parent to stay the same, however i also expected the view ID to change between 3 different IDs (let's call them X, Y and Z) corresponding to my 3 items. It was my understanding that within such a list, each item has their own view (and thus ID.)

Thank you for any clarification you might offer.


Solution

  • I run some code myself and verified that this also occurs to me.

    As you should already know onItemSelectedListener interface belongs to the AdapterView class. In the javadocs of this class you will find these useful info:

        /**
         * <p>Callback method to be invoked when an item in this view has been
         * selected. This callback is invoked only when the newly selected
         * position is different from the previously selected position or if
         * there was no selected item.</p>
         *
         * Implementers can call getItemAtPosition(position) if they need to access the
         * data associated with the selected item.
         *
         * @param parent The AdapterView where the selection happened
         * @param view The view within the AdapterView that was clicked
         * @param position The position of the view in the adapter
         * @param id The row id of the item that is selected
         */
        void onItemSelected(AdapterView<?> parent, View view, int position, long id);
    

    Your first expectation is correct. The parent parameter of onItemSelected refers to the AdapterView that is associated with that spinner. As a result there's only one parent that has a specific id.

    Your second expectation is wrong although it seems logical at first thought. Let's dive deeper into the implementation under the hood.

    When you use a Spinner at some point in your Activity or Fragment you will do the following:

    Spinner spinner = (Spinner) findViewById(R.id.spinner);
    
    // Create an ArrayAdapter using the string array and a default spinner layout
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
        R.array.planets_array, android.R.layout.simple_spinner_item);
    
    // Specify the layout to use when the list of choices appears
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    
    // Apply the adapter to the spinner
    spinner.setAdapter(adapter);
    

    Explanation:

    As stated in the documentation the createFromResource() method allows you to create an ArrayAdapter from the string array. The third argument for this method is a layout resource that defines how the selected choice appears in the spinner control. The simple_spinner_item layout is provided by the platform and is the default layout you should use unless you'd like to define your own layout for the spinner's appearance.

    You should then call setDropDownViewResource(int) to specify the layout the adapter should use to display the list of spinner choices (simple_spinner_dropdown_item is another standard layout defined by the platform).

    If you open these two xml files the simple_spinner_item file has a plain TextView and the simple_spinner_dropdown_item has a plain CheckedTextView. You will also notice that they both have an id defined as:

    android:id="@android:id/text1"
    

    Conclusion:

    So, it's clear that since all your spinner items are using the same xml layout file then they use the same CheckedTextView with the same attributes and thus the same id.