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

余生长醉 提交于 2020-01-04 06:34:12

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!