Ce que vous pouvez faire, c'est décorer votre SpinnerAdapter
avec une autre qui présente une vue "Sélectionner une option...". pour que le Spinner s'affiche initialement sans être sélectionné.
Voici un exemple fonctionnel testé pour Android 2.3, et 4.0 (il n'utilise rien dans la bibliothèque de compatibilité, donc il devrait fonctionner pendant un certain temps) Comme c'est un décorateur, il devrait être facile de réadapter le code existant et il fonctionne bien avec CursorLoader
s également. (Passez le curseur sur l'enveloppe cursorAdapter
bien sûr...)
Il existe un bug Android qui rend la réutilisation des vues un peu plus difficile. (Vous devez donc utiliser le setTag
ou autre chose pour garantir que votre convertView
est correct). Le Spinner ne prend pas en charge les types de vues multiples
Notes de code : 2 constructeurs
Cela vous permet d'utiliser une invite standard ou de définir votre propre "rien de sélectionné" comme première ligne, ou les deux, ou aucune. (Remarque : certains thèmes affichent une liste déroulante pour un Spinner au lieu d'une boîte de dialogue. La liste déroulante n'affiche normalement pas l'invite).
Vous définissez une mise en page pour qu'elle " ressemble " à une invite, par exemple, en grisé...
En utilisant une invite standard (remarquez que rien n'est sélectionné) :
Ou avec une invite et quelque chose de dynamique (on aurait pu aussi ne pas avoir d'invite) :
Utilisation dans l'exemple ci-dessus
Spinner spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.planets_array, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setPrompt("Select your favorite Planet!");
spinner.setAdapter(
new NothingSelectedSpinnerAdapter(
adapter,
R.layout.contact_spinner_row_nothing_selected,
// R.layout.contact_spinner_nothing_selected_dropdown, // Optional
this));
contact_spinner_row_nothing_selected.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerItemStyle"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:textSize="18sp"
android:textColor="#808080"
android:text="[Select a Planet...]" />
RienSelectedSpinnerAdapter.java
import android.content.Context;
import android.database.DataSetObserver;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.SpinnerAdapter;
/**
* Decorator Adapter to allow a Spinner to show a 'Nothing Selected...' initially
* displayed instead of the first choice in the Adapter.
*/
public class NothingSelectedSpinnerAdapter implements SpinnerAdapter, ListAdapter {
protected static final int EXTRA = 1;
protected SpinnerAdapter adapter;
protected Context context;
protected int nothingSelectedLayout;
protected int nothingSelectedDropdownLayout;
protected LayoutInflater layoutInflater;
/**
* Use this constructor to have NO 'Select One...' item, instead use
* the standard prompt or nothing at all.
* @param spinnerAdapter wrapped Adapter.
* @param nothingSelectedLayout layout for nothing selected, perhaps
* you want text grayed out like a prompt...
* @param context
*/
public NothingSelectedSpinnerAdapter(
SpinnerAdapter spinnerAdapter,
int nothingSelectedLayout, Context context) {
this(spinnerAdapter, nothingSelectedLayout, -1, context);
}
/**
* Use this constructor to Define your 'Select One...' layout as the first
* row in the returned choices.
* If you do this, you probably don't want a prompt on your spinner or it'll
* have two 'Select' rows.
* @param spinnerAdapter wrapped Adapter. Should probably return false for isEnabled(0)
* @param nothingSelectedLayout layout for nothing selected, perhaps you want
* text grayed out like a prompt...
* @param nothingSelectedDropdownLayout layout for your 'Select an Item...' in
* the dropdown.
* @param context
*/
public NothingSelectedSpinnerAdapter(SpinnerAdapter spinnerAdapter,
int nothingSelectedLayout, int nothingSelectedDropdownLayout, Context context) {
this.adapter = spinnerAdapter;
this.context = context;
this.nothingSelectedLayout = nothingSelectedLayout;
this.nothingSelectedDropdownLayout = nothingSelectedDropdownLayout;
layoutInflater = LayoutInflater.from(context);
}
@Override
public final View getView(int position, View convertView, ViewGroup parent) {
// This provides the View for the Selected Item in the Spinner, not
// the dropdown (unless dropdownView is not set).
if (position == 0) {
return getNothingSelectedView(parent);
}
return adapter.getView(position - EXTRA, null, parent); // Could re-use
// the convertView if possible.
}
/**
* View to show in Spinner with Nothing Selected
* Override this to do something dynamic... e.g. "37 Options Found"
* @param parent
* @return
*/
protected View getNothingSelectedView(ViewGroup parent) {
return layoutInflater.inflate(nothingSelectedLayout, parent, false);
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
// Android BUG! http://code.google.com/p/android/issues/detail?id=17128 -
// Spinner does not support multiple view types
if (position == 0) {
return nothingSelectedDropdownLayout == -1 ?
new View(context) :
getNothingSelectedDropdownView(parent);
}
// Could re-use the convertView if possible, use setTag...
return adapter.getDropDownView(position - EXTRA, null, parent);
}
/**
* Override this to do something dynamic... For example, "Pick your favorite
* of these 37".
* @param parent
* @return
*/
protected View getNothingSelectedDropdownView(ViewGroup parent) {
return layoutInflater.inflate(nothingSelectedDropdownLayout, parent, false);
}
@Override
public int getCount() {
int count = adapter.getCount();
return count == 0 ? 0 : count + EXTRA;
}
@Override
public Object getItem(int position) {
return position == 0 ? null : adapter.getItem(position - EXTRA);
}
@Override
public int getItemViewType(int position) {
return 0;
}
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public long getItemId(int position) {
return position >= EXTRA ? adapter.getItemId(position - EXTRA) : position - EXTRA;
}
@Override
public boolean hasStableIds() {
return adapter.hasStableIds();
}
@Override
public boolean isEmpty() {
return adapter.isEmpty();
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
adapter.registerDataSetObserver(observer);
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
adapter.unregisterDataSetObserver(observer);
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return position != 0; // Don't allow the 'nothing selected'
// item to be picked.
}
}
7 votes
La solution parfaite réside dans cette question : stackoverflow.com/questions/9863378/ Remplacez simplement la méthode getDropDownView().
0 votes
Avez-vous essayé de régler le premier élément de votre adaptateur sur "Select One" ?
0 votes
[Voici une autre solution intéressante] [1] [1] : stackoverflow.com/questions/9863378/
0 votes
Spinner réutilisable : github.com/henrychuangtw/ReuseSpinner
1 votes
Android--code.blogspot.in/2015/08/Android-spinner-hint.html un autre bon tutoriel
0 votes
Il existe une bien meilleure solution - Utilisez AutocompleteTextView, et définissez clickable et focusable sur false. Ajoutez les éléments sous forme de liste de suggestions. Enveloppez l'AutocompleteTextView dans un TextInputLayout et vous pouvez définir un indice. Ainsi, l'indice est initialement affiché, et lorsque vous cliquez dessus, la liste de suggestions (vos éléments) s'affiche. Les options clickable et focusable on false empêcheront le clavier de s'afficher et toute saisie manuelle, ce qui en fait un menu déroulant parfait.