According to Android documentation, Material Design style is supported for Spinner widget.
So I decided to use it in my app placing it on top of the Toolbar.
<
I know this is late but I came accross this question when I encountered this problem myself and I found a solution in the BrowseSessionsActivity of the Google I/O 2014 app and adapted it.
toolbar_spinner.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<Spinner
android:id="@+id/toolbar_spinner"
style="@style/Widget.MyApp.HeaderBar.Spinner"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
</LinearLayout>
toolbar_spinner_item_actionbar.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawablePadding="8dp"
android:drawableRight="@drawable/spinner_triangle"
android:fontFamily="sans-serif"
android:paddingLeft="16dp"
android:paddingRight="4dp"
android:textColor="#ffffffff"
android:textSize="18dp"
android:textStyle="bold"/>
</LinearLayout>
The spinner_triangle
drawable can be found here.
toolbar_spinner_item_dropdown.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="48dp"
android:drawablePadding="8dp"
android:gravity="center_vertical|start"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:textColor="#ff333333"
android:textSize="16sp"/>
</LinearLayout>
toolbar_spinner.xml
uses the following style.
<style name="Widget.MyApp.HeaderBar.Spinner" parent="Widget.AppCompat.Light.Spinner.DropDown.ActionBar">
<item name="android:background">?android:selectableItemBackground</item>
<item name="android:dropDownSelector">?android:selectableItemBackground</item>
<item name="android:divider">@null</item>
<item name="android:overlapAnchor">true</item>
</style>
This adapter will need to be changed to match your own needs. getTitle()
returns the text for each item shown in the spinner.
private class YourObjectSpinnerAdapter extends BaseAdapter {
private List<YourObject> mItems = new ArrayList<>();
public void clear() {
mItems.clear();
}
public void addItem(YourObject yourObject) {
mItems.add(yourObject);
}
public void addItems(List<YourObject> yourObjectList) {
mItems.addAll(yourObjectList);
}
@Override
public int getCount() {
return mItems.size();
}
@Override
public Object getItem(int position) {
return mItems.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getDropDownView(int position, View view, ViewGroup parent) {
if (view == null || !view.getTag().toString().equals("DROPDOWN")) {
view = getLayoutInflater().inflate(R.layout.toolbar_spinner_item_dropdown, parent, false);
view.setTag("DROPDOWN");
}
TextView textView = (TextView) view.findViewById(android.R.id.text1);
textView.setText(getTitle(position));
return view;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null || !view.getTag().toString().equals("NON_DROPDOWN")) {
view = getLayoutInflater().inflate(R.layout.
toolbar_spinner_item_actionbar, parent, false);
view.setTag("NON_DROPDOWN");
}
TextView textView = (TextView) view.findViewById(android.R.id.text1);
textView.setText(getTitle(position));
return view;
}
private String getTitle(int position) {
return position >= 0 && position < mItems.size() ? mItems.get(position).title : "";
}
}
Toolbar toolbar = getActionBarToolbar();
View spinnerContainer = LayoutInflater.from(this).inflate(R.layout.toolbar_spinner,
toolbar, false);
ActionBar.LayoutParams lp = new ActionBar.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
toolbar.addView(spinnerContainer, lp);
YourObjectSpinnerAdapter spinnerAdapter = new YourObjectSpinnerAdapter();
spinnerAdapter.addItems(getMyObjectSpinnerData());
Spinner spinner = (Spinner) spinnerContainer.findViewById(R.id.toolbar_spinner);
spinner.setAdapter(spinnerAdapter);
I am struggling with the exact same problem.
Try to change the dropdown view resource. At least, this fixed the text color issue for me - however the arrow icon color is still dark. So this is just a partial workaround.
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
For correct Spinner icon tinting you can also just inflate the spinner from code:
spinner_toolbar.xml:
<?xml version="1.0" encoding="utf-8"?>
<Spinner xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/spinner_toolbar"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
Then you have to attach the Spinner to the Toolbar in your Activity:
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getSupportActionBar().getThemedContext(),
R.array.planets_array, R.layout.support_simple_spinner_dropdown_item);
adapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
// we inflate the spinner with the themed Toolbar context -> correct icon tinting
LayoutInflater.from(getSupportActionBar().getThemedContext()).inflate(R.layout.spinner_toolbar, tb, true);
Spinner spinner = (Spinner) toolbar.findViewById(R.id.spinner_toolbar);
spinner.setAdapter(adapter);
However, this uses the app:theme instead of the app:popupTheme for the whole Spinner, including the dropdown menu. Hence, the Spinner icon and text will be colored correctly, but the dropdown menu also has the style of the toolbar and not of the popupTheme.
So if you want to have a dark Toolbar and a light dropdown menu, you would need to fix the dropdown style somehow, for example by creating a custom style for the spinner that specifies a white background and a custom dropdown view with a dark text color.
Maybe somebody else has a better solution on how the app:popupTheme can be propagated to the Spinner dropdown menu.
A simple way that isn't perfect, but uniform enough for both 4.x and 5.0
I removed the <Spinner>
from the layout files and added it programmatically - that allowed for the white triangle to show up properly.
I also created a dropdown item layout using the appcompat required color.
layout/spinner_dropdown_item.xml, note the android:background="@color/primaryColor"
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:background="@color/primaryColor"
android:minHeight="?android:attr/listPreferredItemHeightSmall" />
And in the activity:
SpinnerAdapter spinnerAdapter = ArrayAdapter.createFromResource(getApplicationContext(), R.array.your_array, R.layout.spinner_dropdown_item);
Spinner navigationSpinner = new Spinner(getSupportActionBar().getThemedContext());
navigationSpinner.setAdapter(spinnerAdapter);
toolbar.addView(navigationSpinner, 0);
It's not perfect and the items don't highlight when you click on them, but it's good enough while we wait for the future appcompat libraries to fix these problems (here's hoping anyway).
Had the exact same issue with the spinner's
What i did was to add a custom theme to spinner
<Spinner
android:id="@+id/spinner1"
android:layout_width="match_parent"
android:layout_height="30sp"
android:entries="@array/guest_type"
android:prompt="@string/guesttype"
android:theme="@style/AppTheme1" />
styles.xml
<style name="AppTheme1" parent="Theme.AppCompat.Light">
<item name="android:spinnerDropDownItemStyle">@style/mySpinnerItemStyle</item>
</style>
<style name="mySpinnerItemStyle" parent="@android:style/Widget.Holo.DropDownItem.Spinner">
<item name="android:textColor">#000000</item>
</style>
When i used spinner it crashed (Android 2.3.3 - 2.3.7).
So i try to use TintSpinner now it's not crashing, Try your self as a Optional solution
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.internal.widget.TintSpinner
android:id="@+id/toolbar_spinner"
style="@style/HeaderBar.Spinner"
android:layout_width="wrap_content"
android:layout_height="match_parent"/>
</LinearLayout>
And use below code to cast your toolbar
View spinnerContainer = LayoutInflater.from(this).inflate(R.layout.toolbar_spinner, toolbarTop, false);
ActionBar.LayoutParams lp = new ActionBar.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
toolbarTop.addView(spinnerContainer, lp);
ToolBarSpinnerAdapter spinnerAdapter = new ToolBarSpinnerAdapter(getLayoutInflater());
String[] items = getResources().getStringArray(R.array.action_dropdown);
spinnerAdapter.addItems(items);
TintSpinner mNavigationSpinner = (TintSpinner) spinnerContainer.findViewById(R.id.toolbar_spinner);
mNavigationSpinner.setAdapter(spinnerAdapter);