Change spinner style in toolbar

2019-01-23 13:28发布

问题:

I am trying to put a spinner in my Toolbar like the old ActionBar style navigation and my theme is this

<style name="AppBaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/color_primary</item>
    <item name="colorPrimaryDark">@color/color_primary_dark</item>
    <item name="colorAccent">@color/color_primary</item>
</style>

but my spinner is black while all other icons and overflow menus are white so it looks bad

I tried changing the style of the spinner using this

<style name="ToolbarSpinnerTheme" parent="Theme.AppCompat">
    <item name="android:spinnerItemStyle">@style/TextAppearanceSpinnerItem</item>
</style>

<style name="TextAppearanceSpinnerItem">
    <item name="android:textColor">#FFFFFF</item>
</style>

this is how my Toolbar is styled

<android.support.v7.widget.Toolbar
           android:id="@+id/toolbar"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:minHeight="?attr/actionBarSize"
           android:background="?attr/colorPrimary"
           app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
           app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

           <Spinner
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:id="@+id/modes"
               android:minWidth="150dp"
               android:gravity="bottom"
               style="@style/ToolbarSpinnerTheme"/>

       </android.support.v7.widget.Toolbar>


final Spinner mode = (Spinner)findViewById(R.id.modes);

    SpinnerAdapter mSpinner = ArrayAdapter.createFromResource(this, R.array.action_bar_spinner, android.R.layout.simple_spinner_dropdown_item);
    mode.setAdapter(mSpinner);

but it always stays black. How can I change the spinner arrow and text to white while still keeping the same theme for the dropdown style as you would get with the Light theme?

Update 4.4 arrow fix:

The only way I got the arrow to turn white is to add the spinner programatically and not in xml so it looks something like this

final ArrayAdapter spinnerAdapter = ArrayAdapter.createFromResource(getSupportActionBar().getThemedContext(),
        R.array.main_navigation_list, R.layout.spinner_text);
spinnerAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
mNavigationTags = getResources().getStringArray(R.array.main_navigation_list);


mNavigationSpinner = new Spinner(getSupportActionBar().getThemedContext());
mNavigationSpinner.setAdapter(spinnerAdapter);

mNavigationSpinner.setOnItemSelectedListener(this);
mToolbar.addView(mNavigationSpinner)

回答1:

When you create the arrayadapter you should do getApplicationContext instead of this:

SpinnerAdapter mSpinner = ArrayAdapter.createFromResource(getApplicationContext(), R.array. action_bar_spinner, android.R.layout.simple_spinner_dropdown_item);

Make a new layout file:

<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
                 android:id="@android:id/text1"
                 style="?android:attr/spinnerDropDownItemStyle"
                 android:singleLine="true"
                 android:layout_width="match_parent"
                 android:layout_height="?android:attr/listPreferredItemHeight"
                 android:ellipsize="marquee"
                 android:textColor="#000000"/>

Then change your code to this:

ArrayAdapter mAdapter = ArrayAdapter.createFromResource(getApplicationContext(), R.array. action_bar_spinner, android.R.layout.simple_spinner_dropdown_item);
        mAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
        mode.setAdapter(mAdapter);

Have you tried putting the spinner in the xml file like this:

<android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_height="?attr/actionBarSize"
        android:layout_width="match_parent"
        android:background="?attr/colorPrimary">

    <Spinner
            android:id="@+id/spinner_nav"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

</android.support.v7.widget.Toolbar>

And also disable the title like this:

Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);

Answer is from Chris Banes: https://stackoverflow.com/a/26511653/2767703



回答2:

I do it like the following:

navigation_toolbar.xml

<android.support.v7.widget.Toolbar     xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_width="fill_parent"
android:layout_height="?attr/actionBarSize"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
</android.support.v7.widget.Toolbar>

MainActivity.java

ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
                R.array.pass_type, R.layout.layout_drop_title);
 adapter.setDropDownViewResource(R.layout.layout_drop_list);

 Spinner mNavigationSpinner = new Spinner(getSupportActionBar().getThemedContext());
 mNavigationSpinner.setAdapter(adapter);
 getToolbar().addView(mNavigationSpinner);

You will find I used custom spinner item layout, layout_drop_title and layout_drop_list

layout_drop_title.xml

 <TextView xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@android:id/text1"
    style="?attr/spinnerDropDownItemStyle"
    android:singleLine="true"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:textColor="@color/white"
    android:ellipsize="marquee"/>

layout_drop_list.xml

<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerDropDownItemStyle"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:ellipsize="marquee"
android:background="@color/nliveo_blue_colorPrimary"
android:textColor="@color/white"/>


回答3:

Kevin is in the right direction but the real answer is not to use the application context but the already themed context of the action bar itself. This is actually mentioned in the documenation but it doesn't get that much emphasis all along:

When inflating anything to be displayed on the action bar (such as a SpinnerAdapter for list navigation in the toolbar), make sure you use the action bar’s themed context, retrieved via getSupportActionBar().getThemedContext().



回答4:

only two changes reqired

My Pic

my spinner

Spinner xml

and last change in MainActivity

MainActivity.java