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>
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 callonItemSelected
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(...)
:The key point is to call
spinner.setSelection(0, true)
with thetrue
parameter. Otherwise, if you just callspinner.setSelection(0)
, the Viewv
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.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