Como defino um tema diferente para o menu suspenso de um Spinner?

102

Um exemplo de uso:

insira a descrição da imagem aqui

O Spinner tem um tema escuro, mas quero que o menu suspenso seja um tema claro.

Chris Banes
fonte

Respostas:

195

Android M

Novo no Android 6.0, o Spinner agora tem o android:popupThemeparâmetro que permite definir o tema usado para o pop-up (menu suspenso).

Você pode usá-lo como:

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

Isso funcionará em dispositivos com API de nível 23+, mas não em dispositivos que executam uma versão anterior do Android.

AppCompat

É aqui que entra o AppCompat. Sua implementação Spinner também oferece suporte popupTheme, mas é um pouco mais envolvente para acertar.

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

Depois disso, você precisa atualizar seu adaptador para poder funcionar com o AppCompat. Você pode fazer isso implementando a nova ThemedSpinnerAdapterinterface.

public class MyAdapter extends BaseAdapter implements ThemedSpinnerAdapter {

   Theme getDropDownViewTheme() { ... }

   void setDropDownViewTheme(Theme theme) { ... }

}

Esses métodos são usados ​​pelo Spinner para informar ao adaptador qual tema usar para aumentar as visualizações suspensas. Para tornar isso o mais fácil possível, oferecemos a você uma Helperclasse que você pode conectar ao seu adaptador.

Isso significa que seu adaptador se torna 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
fonte
Olá, não consegui encontrar o ThemedSpinnerAdapter dentro do appcompat-v7. Estou usando a versão 22.2.1. Tenho que fazer algo diferente para importá-lo?
Douglas Alves
3
@DouglasAlves use o mais recente 23.0.0
khusrav
Parece que o Android Studio não sabe sobre o atributo app: popupTheme Spinner: "Prefixo de namespace inesperado" app "encontrado para tag Spinner". O Lint também falha com o mesmo erro.
makovkastar
1
@Chris Banes: Fornece a lista suspensa com um fundo escuro, independente do tema que você usa.
Ashwin de
2
ele deve usar "android.support.v7.widget.AppCompatSpinner" em vez de "spinner" no xml?
Angel Koh
2

para seta giratória, usei android:backgroundTint="@color/white"que funcionará a partir da API 21

para visualização giratória e visualização suspensa:

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

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

para getView (), o adaptador usará spinner_item.xml

para getDropDownView (), o adaptador usará dropdwon_item.xml

então você pode usar seus layouts personalizados como quiser

espero que ajude

bsma
fonte
0

Apenas para referência, se você usar o, CursorAdaptersua implementação pode ser muito mais fácil, apenas substitua newView(), não há necessidade de substituir getDropDownView()lá:

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

você pode tentar isso: na pasta de layout, faça um 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" />

então use este código:

spinnerAdapter = new ArrayAdapter<String>(R.layout.spinner_item,items);
Ahmad Azarnia
fonte
6
Acho que porque é bastante óbvio, não responde à pergunta. A questão é sobre como definir um tema, não vejo nenhuma referência ao tema nesta resposta. Só para ficarmos claros, eu não votei contra isso, outros já fizeram o suficiente.
2Dee