问题
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>
回答1:
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
来源:https://stackoverflow.com/questions/33908564/setting-spinner-text-color-programmatically-lags-is-slow-is-wrong-color-for-sp