Setting spinner text color programmatically lags, is slow, is wrong color for split second

android, spinner

Solution

What I was doing wrong:

Before, I was following the advice of this answer, and setting the text color in the `onItemSelected` method, but that method is only called automatically after the UI is done, and you cannot call `onItemSelected` directly from your code. That was causing a lag. (But it is still needed for when you choose an item from the drop down list - see my solution to this question.)

Solution:

The strategy is to obtain the "Selected" view and set its text color before onCreate finishes. When I tested it in the debugger, no UI is shown during the `onCreate` method, so this is guaranteed to work.

I just had to add this code after the call to `setAdapter(...)`:

//Set the text color of the Spinner's selected view (not a drop down list view)
spinner.setSelection(0, true);
View v = spinner.getSelectedView();
((TextView)v).setTextColor(backgroundColor);

The key point is to call `spinner.setSelection(0, true)` with the `true` parameter. Otherwise, if you just call `spinner.setSelection(0)`, the View `v` would be null. I found out about this thanks to this answer.

Complete method:

Here is the complete method. NOTE: The code in `onItemSelected` still needs to be there! Because otherwise, every time you select an item from the drop down list, it will have the wrong color.

@Override 
protected void onCreate(Bundle savedInstanceState)
{ 
    Spinner spinner = (Spinner) findViewById(R.id.spinner);

    //Get rid of the normal toolbar's title, because the spinner is replacing the title. 
    getSupportActionBar().setDisplayShowTitleEnabled(false); 

    //Set the choices on the spinner by setting the adapter. 
    spinner.setAdapter(new SpinnerAdapter(toolbar.getContext(), new String[]{"Overview", "Story", "Specifications", "Poll", "Video"}, accentColor, backgroundColor));

    //Set the text color of the Spinner's selected view (not a drop down list view)
    spinner.setSelection(0, true);
    View v = spinner.getSelectedView();
    ((TextView)v).setTextColor(backgroundColor);

    //Set the listener for when each option is clicked. 
    spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
    { 

        @Override 
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
        { 
           //Change the selected item's text color 
           ((TextView) view).setTextColor(backgroundColor);
        } 

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

} 

For more info on the source code of the setSelection methods, see the AbsSpinner.java code here: https://android.googlesource.com/platform/frameworks/base/+/jb-release/core/java/android/widget/AbsSpinner.java

And here is Spinner.java in case it helps: https://android.googlesource.com/platform/frameworks/base/+/jb-release/core/java/android/widget/Spinner.java

Problem

TLDR: My spinner displays the wrong color for a split second. I have a problem with my spinner. Whenever I run the app, if the activity is not cached in memory, it sometimes lags. The text is a default color (like black) before I can set it to the right color. It looks really unprofessional. Video: Please watch this screen recording to see this in action: https://drive.google.com/file/d/0By2AG5yaBEhMRnRsbVBDU251STQ/view How it looks for one split-second while loading the page: How it looks after the lag time (and how it is supposed to look from the start): Code: ``` public class MyActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { Spinner spinner = (Spinner) findViewById(R.id.spinner); //Get rid of the normal toolbar's title, because the spinner is replacing the title. getSupportActionBar().setDisplayShowTitleEnabled(false); //Set the choices on the spinner by setting the adapter. spinner.setAdapter(new SpinnerAdapter(toolbar.getContext(), new String[]{"Overview", "Story", "Specifications", "Poll", "Video"}, accentColor, backgroundColor)); //Set the listener for when each option is clicked. spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { //Change the selected item's text color ((TextView) view).setTextColor(backgroundColor); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); } } ``` XML: ``` <?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/ColorPrimary" android:elevation="4dp"> <Spinner android:id="@+id/spinner" app:popupTheme="@style/AppTheme.PopupOverlay" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </android.support.v7.widget.Toolbar> ```

Original source

Related problems