Как установить другую тему для раскрывающегося списка Spinner?

102

Пример использования:

введите описание изображения здесь

Spinner выполнен в темной тематике, но я хочу, чтобы раскрывающийся список был светлым.

Крис Бэйнс
источник

Ответы:

195

Android M

Новое в Android 6.0, Spinner теперь имеет android:popupThemeпараметр, который позволяет вам установить тему, используемую для всплывающего окна (раскрывающегося списка).

Вы можете использовать это так:

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

Это будет работать на устройствах с API уровня 23+, но не на устройствах с более ранней версией Android.

AppCompat

Здесь на помощь приходит AppCompat. Его реализация Spinner также поддерживает popupTheme, но для правильной работы требуется немного больше усилий.

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

После этого вам необходимо обновить адаптер, чтобы иметь возможность работать с AppCompat. Вы делаете это, заставляя его реализовать новый ThemedSpinnerAdapterинтерфейс.

public class MyAdapter extends BaseAdapter implements ThemedSpinnerAdapter {

   Theme getDropDownViewTheme() { ... }

   void setDropDownViewTheme(Theme theme) { ... }

}

Эти методы используются Spinner, чтобы иметь возможность сообщить адаптеру, какую тему использовать для расширения любых раскрывающихся представлений. Чтобы сделать это как можно проще, мы предоставили вам Helperкласс, который вы можете подключить к своему адаптеру.

Это означает, что ваш адаптер становится примерно таким:

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();
  }
}
Крис Бэйнс
источник
Привет, мне не удалось найти ThemedSpinnerAdapter внутри appcompat-v7. Пользуюсь версией 22.2.1. Нужно ли мне делать что-то другое, чтобы импортировать его?
Дуглас Алвес,
3
@DouglasAlves использует новейшую версию 23.0.0
khusrav
Похоже, что Android Studio не знает об атрибуте app: popupTheme Spinner: «Для тега Spinner найден неожиданный префикс пространства имен». Lint также не работает с той же ошибкой.
makovkastar
1
@Chris Banes: выпадающий список отображается на темном фоне, независимо от используемой темы.
Ashwin
2
должен ли он использовать android.support.v7.widget.AppCompatSpinner вместо spinner в xml?
Angel Koh
2

для стрелки прядильщика, которую я использовал, android:backgroundTint="@color/white"это будет работать с API 21

для просмотра счетчика и раскрывающегося списка:

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

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

для getView () адаптер будет использовать spinner_item.xml

для getDropDownView () адаптер будет использовать dropdwon_item.xml

тогда вы можете использовать свои собственные макеты по своему усмотрению

Надеюсь, поможет

bsma
источник
0

Просто для справки, если вы используете CursorAdapterвашу реализацию, может быть намного проще, просто переопределите newView(), не нужно переопределять getDropDownView()там:

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    return mDropDownHelper.getDropDownViewInflater().inflate(R.layout.list_item, parent, false);
}
rekire
источник
-5

вы можете попробовать это: в папке макета создайте 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" />

затем используйте этот код:

spinnerAdapter = new ArrayAdapter<String>(R.layout.spinner_item,items);
Ахмад Азарния
источник
6
Я думаю, потому что это довольно очевидно, он не отвечает на вопрос. Вопрос в том, чтобы установить тему, я не вижу в этом ответе ссылки на тематику. Просто чтобы нам было понятно, я не отрицал это, другие уже сделали это достаточно.
Смотрите