¿Cómo configuro un tema diferente para el menú desplegable de un Spinner?

102

Un ejemplo de uso:

ingrese la descripción de la imagen aquí

El Spinner tiene un tema oscuro, pero quiero que el menú desplegable tenga un tema claro.

Chris Banes
fuente

Respuestas:

195

Android M

Como novedad en Android 6.0, Spinner ahora tiene el android:popupThemeparámetro que le permite configurar el tema utilizado para la ventana emergente (menú desplegable).

Puedes usarlo como tal:

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

Eso funcionará en dispositivos con nivel de API 23+, pero no en dispositivos con una versión inferior de Android.

AppCompat

Aquí es donde entra AppCompat. Su implementación Spinner también es compatible popupTheme, pero es un poco más complicado hacerlo bien.

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

Después de eso, debe actualizar su Adaptador para poder trabajar con AppCompat. Lo haces haciendo que implemente la nueva ThemedSpinnerAdapterinterfaz.

public class MyAdapter extends BaseAdapter implements ThemedSpinnerAdapter {

   Theme getDropDownViewTheme() { ... }

   void setDropDownViewTheme(Theme theme) { ... }

}

Spinner utiliza estos métodos para poder decirle al Adaptador qué tema utilizar para inflar las vistas desplegables. Para que esto sea lo más fácil posible, le hemos proporcionado una Helperclase que puede conectar a su adaptador.

Esto significa que su adaptador se convierte en algo como:

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();
  }
}
Chris Banes
fuente
Hola, no pude encontrar ThemedSpinnerAdapter dentro de appcompat-v7. Estoy usando la versión 22.2.1. ¿Tengo que hacer algo diferente para importarlo?
Douglas Alves
3
@DouglasAlves usa el más nuevo 23.0.0
khusrav
Parece que Android Studio no conoce la aplicación: popupTheme Atributo de Spinner: "Se encontró la aplicación" Prefijo de espacio de nombres inesperado "para la etiqueta Spinner". Lint también falla con el mismo error.
makovkastar
1
@Chris Banes: muestra la lista desplegable con un fondo oscuro, independientemente del tema que uses.
Ashwin
2
¿Debería usar "android.support.v7.widget.AppCompatSpinner" en lugar de "spinner" en el xml?
Angel Koh
2

para la flecha giratoria que he usado, android:backgroundTint="@color/white"esto funcionará desde API 21

para la vista giratoria y la vista desplegable:

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

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

para getView () el adaptador usará spinner_item.xml

para getDropDownView () el adaptador utilizará dropdwon_item.xml

entonces puedes usar tus diseños personalizados como quieras

Espero eso ayude

bsma
fuente
0

Solo como referencia, si usa CursorAdaptersu implementación puede ser mucho más fácil, simplemente anule newView(), no es necesario anular getDropDownView()allí:

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    return mDropDownHelper.getDropDownViewInflater().inflate(R.layout.list_item, parent, false);
}
rekire
fuente
-6

puedes probar esto: en tu carpeta de diseño haz un 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" />

luego usa este código:

spinnerAdapter = new ArrayAdapter<String>(R.layout.spinner_item,items);
Ahmad Azarnia
fuente
6
Supongo que porque es bastante obvio no responde a la pregunta. La pregunta es sobre establecer un tema, no veo ninguna referencia al tema en esta respuesta. Para que quede claro, no voté en contra de esto, otros ya lo han hecho lo suficiente.
Dee