Comment puis-je corriger le style Spinner pour Android 4.x placé en haut de la barre d’outils

Selon la documentation Android , le style Material Design est pris en charge pour le widget Spinner.

J’ai donc décidé de l’utiliser dans mon application en le plaçant au-dessus de la barre d’outils.

layout / activity_base.xml

   

Thème d’activité

  @color/omni_primary_color @color/omni_primary_color_dark @color/omni_accent_color  

BaseActivity.java

 public class BaseActivity extends ActionBarActivity { @InjectView(R.id.my_awesome_toolbar) Toolbar mToolbar; @InjectView(R.id.spinner) Spinner spinner; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_base); ButterKnife.inject(this); //setup toolbar setSupportActionBar(mToolbar); getSupportActionBar().setDisplayShowTitleEnabled(false); mToolbar.setNavigationIcon(R.drawable.ic_action_navigation_menu); ArrayAdapter adapter = ArrayAdapter.createFromResource(mToolbar.getContext(), R.array.planets_array, R.layout.support_simple_spinner_dropdown_item); adapter.setDropDownViewResource(R.layout.support_simple_spinner_dropdown_item); spinner.setAdapter(adapter); } } 

Sur Lollipop spinner et dropdown semble bien, bien que la couleur de fond déroulante soit noire comparée au menu déroulant qui est blanc. Je suppose que cette app:popupTheme="@style/ThemeOverlay.AppCompat.Light" n’est pas propagée au spinner.

Android 5.0

entrer la description de l'image icientrer la description de l'image ici

Maintenant, le gros problème est avec Android 4.x où la couleur de fond déroulante est le blanc (popupTheme propagé?) Et l’icône à côté du spinner est noire.

Android 4.4

entrer la description de l'image ici

Comment puis-je le définir correctement dans le XML ou mettre en œuvre dans le code pour le faire fonctionner sur Android 5 et 4? Idéalement, je voudrais avoir les deux sous Android 5, mais avec un menu déroulant blanc (comme le menu déroulant de réglage).

Mettre à jour

J’ai remarqué que définir la propriété colorControlNormal affecte l’icône de filtre de Spinner. Si quelqu’un découvre comment utiliser cela pour Spinner (sans modifier les autres contrôles de contenu), alors ma solution combinerait cette découverte avec la réponse de @Sven.

Mettre à jour

La modification suivante résout le problème pour le texte Spinner et la couleur popup. Le seul problème de la solution finale est l’icône du filtre.

 ArrayAdapter adapter = ArrayAdapter.createFromResource(getSupportActionBar().getThemedContext(), R.array.planets_array, R.layout.support_simple_spinner_dropdown_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 

Mettre à jour

J’ai trouvé que l’icône de filtre faisait en fait partie d’ android:background spécifié pour le spinner et il est transparent. Fournir son propre arrière-plan le réparerait, par exemple

 ?android:selectableItemBackground 

Mystère résolu!

La dernière pièce du puzzle est la fenêtre contextuelle sur Android 5 qui a un arrière-plan noir et un texte blanc, mais je suppose que cela peut être résolu avec une mise en page personnalisée. Si personne ne donne une réponse complète, je le ferai moi-même et je marquerai comme accepté.

Je sais que c’est en retard mais j’ai rencontré cette question lorsque j’ai rencontré ce problème moi-même et j’ai trouvé une solution dans BrowseSessionsActivity de l’application Google I / O 2014 et je l’ai adaptée.

Mises en page

toolbar_spinner.xml

     

toolbar_spinner_item_actionbar.xml

     

Le fichier spinner_sortingangle peut être trouvé ici .

toolbar_spinner_item_dropdown.xml

     

modes

toolbar_spinner.xml utilise le style suivant.

  

Adaptateur

Cet adaptateur devra être modifié pour répondre à vos propres besoins. getTitle() renvoie le texte de chaque élément affiché dans le compteur.

 private class YourObjectSpinnerAdapter extends BaseAdapter { private List mItems = new ArrayList<>(); public void clear() { mItems.clear(); } public void addItem(YourObject yourObject) { mItems.add(yourObject); } public void addItems(List 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().toSsortingng().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().toSsortingng().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 Ssortingng getTitle(int position) { return position >= 0 && position < mItems.size() ? mItems.get(position).title : ""; } } 

Ajouter le Spinner à votre barre d'outils

 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); 

Résultat

Matériau Spinner

KitKat Spinner

Ne pas implémenter Spinner en XML

 final ArrayAdapter spinnerAdapter = ArrayAdapter.createFromResource(getSupportActionBar().getThemedContext(), R.array.main_navigation_list, R.layout.spinner_text); spinnerAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item); mNavigationTags = getResources().getSsortingngArray(R.array.main_navigation_list); mNavigationSpinner = new Spinner(getSupportActionBar().getThemedContext()); mNavigationSpinner.setAdapter(spinnerAdapter); mNavigationSpinner.setOnItemSelectedListener(this); mToolbar.addView(mNavigationSpinner); 

De cette façon, l’icône à côté de spinner sera blanche

Désolé pour mon mauvais anglais. 🙂 Je pense qu’il est préférable de créer directement le spinner dans Toolbar.

Voici un exemple dans mon fragment.

 public class Testfragment1 extends Fragment { Toolbar mToolbar; Spinner mSpinner; ..... @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ....... mToolbar = (Toolbar) getActivity().findViewById(R.id.toolbar); //you can also set the style with the constructor mSpinner = new Spinner(getActivity()); Ssortingng[] frags = new Ssortingng[]{ "category1", "category2", "category3", }; ArrayAdapter arrayAdapter = new ArrayAdapter(getActivity(),android.R.layout.simple_list_item_1,frags); mSpinner.setAdapter(arrayAdapter); mToolbar.addView(mSpinner); return inflater.inflate(R.layout.fragment_testfragment1, container, false); } ......... @Override public void onDestroyView() { super.onDestroyView(); if (mToolbar != null && mSpinner != null) { mToolbar.removeView(mSpinner); } } } 

Il semble bien sur mon appareil Android 4.1: android-4.1-spinner

Je suis aux sockets avec le même problème.

Essayez de modifier la ressource de vue déroulante. Au moins, cela a corrigé le problème de couleur du texte pour moi – cependant, la couleur de l’icône de la flèche est encore sombre. Donc, ce n’est qu’une solution partielle.

 setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 

Un moyen simple qui n’est pas parfait, mais assez uniforme à la fois pour 4.x et 5.0

img

J’ai retiré le des fichiers de mise en page et l’ai ajouté par programmation – cela a permis au sortingangle blanc de s’afficher correctement.

J’ai également créé une disposition d’élément de liste déroulante en utilisant la couleur requirejse par appcompat.

layout / spinner_dropdown_item.xml, notez l’ android:background="@color/primaryColor"

   

Et dans l’activité:

  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); 

Ce n’est pas parfait et les éléments ne sont pas mis en surbrillance lorsque vous cliquez dessus, mais c’est assez bon pendant que nous attendons les futures bibliothèques appcompat pour résoudre ces problèmes (en espérant de toute façon).

J’ai passé deux jours sur ce problème, mais maintenant, après avoir lu de nombreuses réponses, je peux poster ma solution. J’ai implémenté deux dispositions personnalisées pour l’élément spinner et la fenêtre contextuelle. Définir cet atsortingbut pour spinner: android:background="?android:selectableItemBackground" La flèche noire par défaut du spinner est masquée et nous pouvons utiliser ce que nous préférons. J’ai utilisé la méthode setDropDownVerticalOffset (int) pour gérer la position contextuelle sur les versions antérieures à Android de Lollipop.

Le thème général de mon application est

   

Maintenant, la disposition de l’activité qui contient la barre d’outils et le compteur:

activity_main.xml

      

custom_spinner_toolbar.xml

      

custom_spinner_dropdown_item.xml

    

SpinnerAdapter.java

 public class SpinnerAdapter extends BaseAdapter { private Context mContext; private List mValuesList; public SpinnerAdapter(Context mContext, List mValuesList) { this.mContext = mContext; this.mValuesList = mValuesList; } @Override public int getCount() { return mValuesList.size(); } @Override public Object getItem(int position) { return mValuesList.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } @Override public View getDropDownView(int position, View view, ViewGroup parent) { if (view == null || !view.getTag().toSsortingng().equals("DROPDOWN")) { LayoutInflater inflater = LayoutInflater.from(mContext); view = inflater.inflate(R.layout.custom_spinner_dropdown_item, parent, false); view.setTag("DROPDOWN"); } TextView textView = (TextView) view.findViewById(R.id.spinner_item_text); textView.setText(getTitle(position)); return view; } @Override public View getView(int position, View view, ViewGroup parent) { if (view == null || !view.getTag().toSsortingng().equals("NON_DROPDOWN")) { LayoutInflater inflater = LayoutInflater.from(mContext); view = inflater.inflate(R.layout.custom_spinner_toolbar, parent, false); view.setTag("NON_DROPDOWN"); } TextView textView = (TextView) view.findViewById(R.id.spinner_item_text); textView.setText(getTitle(position)); return view; } private Ssortingng getTitle(int position) { return position >= 0 && position < mValuesList.size() ? mValuesList.get(position) : ""; } } 

Enfin, la partie pertinente du code source d'activité:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mToolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(mToolbar); final ActionBar actionBar = getSupportActionBar(); actionBar.setDisplayShowTitleEnabled(false); actionBar.setHomeAsUpIndicator(R.drawable.ic_menu); actionBar.setDisplayHomeAsUpEnabled(true); mSpinner = (Spinner) findViewById(R.id.spinner_rss); Ssortingng[] items = getResources().getSsortingngArray(R.array.spinner_rss_items); List spinnerItems = new ArrayList(); for(int i = 0; i < items.length; i++) { spinnerItems.add(items[i]); } SpinnerAdapter adapter = new SpinnerAdapter(actionBar.getThemedContext(), spinnerItems); mSpinner.setAdapter(adapter); if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { mSpinner.setDropDownVerticalOffset(-116); } } 

Ce sont les résultats sur Lollipop et Kitkat:

entrer la description de l'image icientrer la description de l'image icientrer la description de l'image ici

J'espère que cela aide! 🙂

Tu ne peux pas faire ça?

Fichier xml personnalisé pour l’élément spinner: your_spinner.xml:

   

Utilisez cette option pour afficher les articles spinner:

 ArrayAdapter adapter = new ArrayAdapter(this, R.layout.your_spinner,list); 

Ensuite, supprimez la ressource déroulante.

Eu le même problème avec le spinner

Ce que j’ai fait était d’append un thème personnalisé à spinner

   

styles.xml

    

Utilisez la propriété android: dropDownVerticalOffset dans spinner pour obtenir un espacement par rapport au sumt.

  

N’oubliez pas de définir Android: spinnerMode = “dropdown” bien que cela ne fonctionnera pas dans spinnerMode = dialog

Pour une teinte correcte de l’icône Spinner, vous pouvez aussi simplement gonfler le spinner du code:

spinner_toolbar.xml:

   

Ensuite, vous devez attacher le Spinner à la barre d’outils de votre activité:

 ArrayAdapter 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); 

Cependant, cela utilise l’application: theme au lieu de l’application: popupTheme pour tout Spinner, y compris le menu déroulant. Par conséquent, l’icône et le texte Spinner seront colorés correctement, mais le menu déroulant a également le style de la barre d’outils et non du popupTheme.

Donc, si vous voulez avoir une barre d’outils sombre et un menu déroulant clair, vous devrez corriger le style de liste déroulante, par exemple en créant un style personnalisé pour le disque qui spécifie un fond blanc et une vue déroulante personnalisée avec une couleur de texte sombre. .

Peut-être que quelqu’un d’autre a une meilleure solution sur la façon dont l’application: popupTheme peut être propagée dans le menu déroulant Spinner.

Vous pouvez corriger la position déroulante (apparaîtra en haut de la barre d’outils, comme le menu) pour Android 4 en utilisant ce code:

  

Pour reprendre cela, j’avais des problèmes similaires. Mon principal problème était que le texte de ma barre d’outils était plus petit que les dimensions de titre habituelles et la mauvaise couleur. Capture d’écran ici http://s27.postimg.org/v24x1aw43/Screen_Shot_2015_01_11_at_13_36_04.png

Le menu déroulant était correct, mais je vais également passer à la personnalisation.

Permettez-moi également de préciser que ce correctif est principalement basé sur le correctif de @Daniel B, mais ne nécessite pas l’adaptateur personnalisé, pour autant que je puisse dire que rien n’est cassé, mais je ne donne aucune garantie!

  1. Ajoutez un élément spinner normal dans le fichier de disposition XML (dans la barre d’outils).
    
  1. Créer un nouveau fichier de mise en page toolbar_spinner_item_actionbar.xml (Ce sera le matériel affiché pour le spinner dans la barre d’outils)
    
  1. L’adaptateur de votre disque dur rest pratiquement le même, mais changez la disposition du fichier standard android.R.layout.simple_spinner_dropdown_item à R.layout.toolbar_spinner_item_actionbar. Cela va appliquer votre look personnalisé pour le texte de la barre d’outils.

Dans cet exemple, j’ai défini adapter.setDropDownViewResource sur android.R.layout.simple_spinner_dropdown_item, cela applique les valeurs par défaut du thème standard pour la liste déroulante, ce qui me convient.

 ArrayAdapter set1Adapter = new ArrayAdapter(RoutineDetailsActivity.this, R.layout.toolbar_spinner_item_actionbar, set1Actual); set1Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mWeekSpinner.setAdapter(set1Adapter); 

C’est fondamentalement cela, le résultat ici [ne peut pas joindre une image ou append un autre lien car mon représentant est trop faible! Va append dans le commentaire]. Vous pouvez vous arrêter ici, mais vous pouvez changer la couleur de la flèche déroulante.

Techniquement, il s’agit de la teinte correcte pour mon application, cependant, comme ma couleur primaire est déjà la couleur de la barre d’outils, il serait judicieux de personnaliser la flèche.

Configurer une flèche personnalisable

  1. Ajoutez cette ligne à dessiner “android: drawableRight =” @ drawable / spinner_sortingangle “dans le toolbar_spinner_item_actionbar.xml créé plus tôt. Maintenant, cela pourrait être n’importe quelle image, pour l’instant vous pourriez utiliser la ressource de flèche blanche de Daniel B https: //raw.githubusercontent. com / google / iosched / master / android / src / main / res / drawable-xxhdpi / spinner_sortingangle.png .

En cours d’exécution cela se traduira par deux flèches, la flèche blanche et le thème par défaut. Pour résoudre ce problème, ajoutez le style ci-dessous. Encore une fois, cela est tiré du code de Daniel B et pourrait probablement être abrégé, mais pour l’instant cela fonctionne ….

   
  1. Appliquez le style créé au spinner …
    

Le résultat sera quelque chose comme ceci [encore une fois ne peut pas joindre ou un lien, appenda à un commentaire]. Le remplissage peut être défini à partir de la configuration du fichier plus tôt, dans mon cas, je devrais changer la flèche pour correspondre aux icons.

J’espère que ça a du sens.

Lorsque j’ai utilisé Spinner, il s’est écrasé (Android 2.3.3 – 2.3.7).

Donc, j’essaie d’utiliser TintSpinner maintenant, il ne plonge pas, essayez vous-même comme une solution facultative

      

Et utilisez le code ci-dessous pour lancer votre barre d’outils

  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()); Ssortingng[] items = getResources().getSsortingngArray(R.array.action_dropdown); spinnerAdapter.addItems(items); TintSpinner mNavigationSpinner = (TintSpinner) spinnerContainer.findViewById(R.id.toolbar_spinner); mNavigationSpinner.setAdapter(spinnerAdapter); 

J’ai perdu des heures sur ce sujet. Pour autant que je sache, les solutions ci-dessus nécessitent toutes de copier / coller de gros morceaux de code de style appcompat pour réimplémenter des détails de base tels que les états tactiles.

Un moyen relativement simple d’obtenir un comportement de type natif consiste à gonfler la vue par programmation pour s’assurer que le thème est correct, par exemple:

 // Activity has context with 'Theme.AppCompat.Light.NoActionBar' spinner = new AppCompatSpinner(getActivity()); toolbar.addView(spinner); 

Pour que le sortingangle soit blanc plutôt que colorControlNormal , j’ai appliqué une teinte ColorStateList à l’arrière-plan:

 ViewCompat.setBackgroundTintList(spinner, resources.getColorStateList(R.drawable.bg_toolbar_spinner) 

bg_toolbar_spinner.xml

     

Je l’ai résolu en créant de nouvelles valeurs pour les versions 21 et 23 et en ajoutant de nouveaux atsortingbuts dans le style spinner android: dropDownVerticalOffset et supprimez-le du fichier de style par défaut. (mon cas n’est pas lié à la barre d’outils) c’est pour le spinner normal.

Ajouter ce style dans les dossiers 23 et 21

  

Cela fonctionne parfaitement sur toutes les versions. J’espère que cela fonctionne avec vous!