102

An example usage:

enter image description here

The Spinner is dark themed, but I want the dropdown to be light themed.

Chris Banes
  • 31,763
  • 16
  • 59
  • 50

4 Answers4

195

Android M

New in Android 6.0, Spinner now has the android:popupTheme parameter which allows you to set the theme used for the popup (dropdown).

You can use it as so:

<Spinner
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:popupTheme="@android:style/ThemeOverlay.Material.Light" />

That will work on devices running API level 23+, but not on devices running a lower version of Android.

AppCompat

This is where AppCompat comes in. Its Spinner implementation also supports popupTheme, but it's a bit more involved to get right.

<Spinner
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

After that, you need to update your Adapter to be able to work with AppCompat. You do that by making it implement the new ThemedSpinnerAdapter interface.

public class MyAdapter extends BaseAdapter implements ThemedSpinnerAdapter {

   Theme getDropDownViewTheme() { ... }

   void setDropDownViewTheme(Theme theme) { ... }

}

These methods are used by Spinner to be able to tell the Adapter which theme to use for inflating any drop down views. To make this as easy as possible we have given you a Helper class which you can plug in to your adapter.

This means that your adapter becomes something like:

public class MyAdapter extends BaseAdapter implements ThemedSpinnerAdapter {
  private final ThemedSpinnerAdapter.Helper mDropDownHelper;

  public MyAdapter(Context context) { 
    mDropDownHelper = new ThemedSpinnerAdapter.Helper(context);
  }

  @Override
  public View getDropDownView(int position, View convertView, ViewGroup parent) {
    View view;

    if (convertView == null) {
      // Inflate the drop down using the helper's LayoutInflater
      LayoutInflater inflater = mDropDownHelper.getDropDownViewInflater();
      view = inflater.inflate(R.layout.my_dropdown, parent, false);
    }

    // ...

    return view;
  }

  @Override
  public void setDropDownViewTheme(Theme theme) {
    mDropDownHelper.setDropDownViewTheme(theme);
  }

  @Override
  public Theme getDropDownViewTheme() {
    return mDropDownHelper.getDropDownViewTheme();
  }
}
PLNech
  • 3,087
  • 1
  • 23
  • 52
Chris Banes
  • 31,763
  • 16
  • 59
  • 50
  • Hi, I couldn't find ThemedSpinnerAdapter inside the appcompat-v7. I'm using version 22.2.1. Do I have to do anything different to import it? – Douglas Alves Aug 19 '15 at 20:59
  • 3
    @DouglasAlves use newest 23.0.0 – khusrav Aug 20 '15 at 13:46
  • It seems Android Studio doesn't know about the app:popupTheme Spinner attribute: "Unexpected namespace prefix "app" found for tag Spinner". Lint also fails with the same error. – makovkastar Dec 10 '15 at 22:40
  • 1
    @Chris Banes : It gives the drop down list with a dark background, irrespective of the theme you use. – Ashwin Feb 11 '16 at 10:47
  • @Chris Banes : I put a break point inside setDropDownViewTheme(). But it never reaches there. That means setDropDown() is never being called. – Ashwin Feb 11 '16 at 11:01
  • 2
    should it use "android.support.v7.widget.AppCompatSpinner" instead of "spinner" in the xml? – Angel Koh Mar 16 '16 at 02:49
  • Seems this work for a dropdown style spinner but not for spinnerMode="dialog". For a dialog it wont change the theme. Is there really a way to change the appearance of that dialog? – HarshalK Jul 18 '16 at 12:37
  • Last example looks awfully similar to the Android Docs :} – Hack5 Jun 04 '17 at 15:13
  • The spinner jumps around when scrolling with a theme set. Very annoying. – Maarten Feb 22 '19 at 11:47
  • There is a bug specifically in the `AppCompat` version `app:popupTheme`. When I use `android:popupTheme`, it __does__ work correctly (without jumping around). – Maarten Feb 22 '19 at 12:23
2

for spinner's arrow I've used android:backgroundTint="@color/white" this will work from API 21

for spinner view and dropdown view:

ArrayAdapter<Area> areasAdapter = new ArrayAdapter<Area>(getContext(),R.layout.spinner_item, areas);

areasAdapter.setDropDownViewResource(R.layout.dropdwon_item);
areasSpinner.setAdapter(areasAdapter);

for getView() the adapter will use spinner_item.xml

for getDropDownView() the adapter will use dropdwon_item.xml

then you can use your custom layouts as you like

hope it helps

bsma
  • 88
  • 1
  • 10
0

Just for reference if you use the CursorAdapter your implementation can be much easier, just override newView(), no need to override getDropDownView() there:

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    return mDropDownHelper.getDropDownViewInflater().inflate(R.layout.list_item, parent, false);
}
rekire
  • 47,260
  • 30
  • 167
  • 264
-4

you can try this: in your layout folder make a spinner_item.xml:

<TextView 
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:padding="10dp"
android:background = "#ffffff"
android:textColor="@color/primary_text"
android:textSize="@dimen/text_size_normal" />

then use this code:

spinnerAdapter = new ArrayAdapter<String>(R.layout.spinner_item,items);
Ahmad Azarnia
  • 129
  • 1
  • 1
  • 11
  • 6
    I guess because it's fairly obvious it doesn't answer the question. The question is about setting a theme, I see no reference to theming in this answer. Just so we're clear, I didn't downvote this, others have gone at it enough already. – 2Dee Aug 19 '15 at 15:28