18

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

enter image description here

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)
tyczj
  • 71,600
  • 54
  • 194
  • 296

3 Answers3

21

I do it like the following:

enter image description here

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"/>
p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
Mao
  • 1,398
  • 10
  • 8
  • thanks for you edit ,i am not familiar with edit box for stackoverflow and i will grope – Mao Feb 05 '15 at 16:42
  • great, `android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"` along with `app:popupTheme="@style/ThemeOverlay.AppCompat.Light"` were a key for arrow – B-GangsteR Jul 18 '18 at 01:22
9

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().

Gábor
  • 9,466
  • 3
  • 65
  • 79
  • 1
    I just tried using the `ThemeContext` but that didnt change the color of the arrow still – tyczj Jan 07 '15 at 17:55
8

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

Community
  • 1
  • 1
Kevin van Mierlo
  • 9,554
  • 5
  • 44
  • 76