it-swarm.com.de

Wie erstelle ich einen Android Spinner mit dem Starttext "Select One"

In Android möchte ich einen Spinner verwenden, der anfangs (wenn der Benutzer noch keine Auswahl getroffen hat) den Text "Select One" anzeigt. Wenn der Benutzer auf den Spinner klickt, wird die Liste der Elemente angezeigt und der Benutzer wählt eine der Optionen aus. Nachdem der Benutzer eine Auswahl getroffen hat, wird das ausgewählte Element anstelle von "Select One" im Spinner angezeigt.

Ich habe den folgenden Code, um einen Spinner zu erstellen: 

String[] items = new String[] {"One", "Two", "Three"};
Spinner spinner = (Spinner) findViewById(R.id.mySpinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
            Android.R.layout.simple_spinner_item, items);
adapter.setDropDownViewResource(Android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);

Bei diesem Code wird zunächst der Punkt "Eins" angezeigt. Ich könnte den Elementen einfach einen neuen Eintrag "Select One" hinzufügen, aber dann würde "Select One" auch in der Dropdown-Liste als erster Eintrag angezeigt.

Wie kann ich dieses Problem beheben?

512
Pieter Kuijpers

Hier ist eine allgemeine Lösung, die die Sicht Spinner überschreibt. Es setzt setAdapter() außer Kraft, um die Anfangsposition auf -1 zu setzen, und gibt die angegebene Variable SpinnerAdapter aus, um die Eingabeaufforderung für eine Position unter 0 anzuzeigen.

Dies wurde auf Android 1.5 bis 4.2 getestet, aber der Käufer ist vorsichtig! Da diese Lösung auf Reflektion basiert, um die private AdapterView.setNextSelectedPositionInt() und AdapterView.setSelectedPositionInt() aufzurufen, kann die Funktionsfähigkeit in zukünftigen Betriebssystemupdates nicht garantiert werden. Es scheint wahrscheinlich, dass dies der Fall ist, aber es ist keinesfalls garantiert.

Normalerweise würde ich so etwas nicht gutheißen, aber diese Frage wurde oft genug gestellt und es scheint eine vernünftige Anfrage zu sein, dass ich dachte, ich würde meine Lösung posten.

/**
 * A modified Spinner that doesn't automatically select the first entry in the list.
 *
 * Shows the Prompt if nothing is selected.
 *
 * Limitations: does not display Prompt if the entry list is empty.
 */
public class NoDefaultSpinner extends Spinner {

    public NoDefaultSpinner(Context context) {
        super(context);
    }

    public NoDefaultSpinner(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NoDefaultSpinner(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void setAdapter(SpinnerAdapter orig ) {
        final SpinnerAdapter adapter = newProxy(orig);

        super.setAdapter(adapter);

        try {
            final Method m = AdapterView.class.getDeclaredMethod(
                               "setNextSelectedPositionInt",int.class);
            m.setAccessible(true);
            m.invoke(this,-1);

            final Method n = AdapterView.class.getDeclaredMethod(
                               "setSelectedPositionInt",int.class);
            n.setAccessible(true);
            n.invoke(this,-1);
        } 
        catch( Exception e ) {
            throw new RuntimeException(e);
        }
    }

    protected SpinnerAdapter newProxy(SpinnerAdapter obj) {
        return (SpinnerAdapter) Java.lang.reflect.Proxy.newProxyInstance(
                obj.getClass().getClassLoader(),
                new Class[]{SpinnerAdapter.class},
                new SpinnerAdapterProxy(obj));
    }



    /**
     * Intercepts getView() to display the Prompt if position < 0
     */
    protected class SpinnerAdapterProxy implements InvocationHandler {

        protected SpinnerAdapter obj;
        protected Method getView;


        protected SpinnerAdapterProxy(SpinnerAdapter obj) {
            this.obj = obj;
            try {
                this.getView = SpinnerAdapter.class.getMethod(
                                 "getView",int.class,View.class,ViewGroup.class);
            } 
            catch( Exception e ) {
                throw new RuntimeException(e);
            }
        }

        public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
            try {
                return m.equals(getView) && 
                       (Integer)(args[0])<0 ? 
                         getView((Integer)args[0],(View)args[1],(ViewGroup)args[2]) : 
                         m.invoke(obj, args);
            } 
            catch (InvocationTargetException e) {
                throw e.getTargetException();
            } 
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        protected View getView(int position, View convertView, ViewGroup parent) 
          throws IllegalAccessException {

            if( position<0 ) {
                final TextView v = 
                  (TextView) ((LayoutInflater)getContext().getSystemService(
                    Context.LAYOUT_INFLATER_SERVICE)).inflate(
                      Android.R.layout.simple_spinner_item,parent,false);
                v.setText(getPrompt());
                return v;
            }
            return obj.getView(position,convertView,parent);
        }
    }
}
244
emmby

Sie können Ihr SpinnerAdapter mit einem dekorieren, das zunächst die Ansicht "Option auswählen ..." enthält, damit der Spinner angezeigt wird, wenn nichts ausgewählt ist.

Hier ist ein funktionierendes Beispiel, das für Android 2.3 und 4.0 getestet wurde (es verwendet nichts in der Kompatibilitätsbibliothek, sollte also eine Weile in Ordnung sein) Funktioniert gut mit CursorLoaders auch. (Tauschen Sie den Cursor auf das umhüllte cursorAdapter, natürlich ...)

Es gibt einen Fehler in Android, der die Wiederverwendung von Ansichten etwas erschwert. (Sie müssen also setTag oder etwas anderes verwenden, um sicherzustellen, dass convertView korrekt ist.) Spinner unterstützt nicht mehrere Ansichtstypen

Code-Hinweise: 2 Konstruktoren

Auf diese Weise können Sie eine Standard-Eingabeaufforderung verwenden oder als erste Zeile oder beides oder gar nichts auswählen. (Hinweis: In einigen Designs wird anstelle eines Dialogfelds ein Dropdown für einen Spinner angezeigt. In der Dropdown-Liste wird normalerweise die Eingabeaufforderung nicht angezeigt.)

Sie definieren ein Layout, das wie eine Eingabeaufforderung 'aussieht', z. B. ausgegraut ...

Initial nothing selected

Verwenden einer Standard-Eingabeaufforderung (beachten Sie, dass nichts ausgewählt ist):

With a standard Prompt

Oder mit einer Eingabeaufforderung und etwas Dynamischem (hätte auch keine Eingabeaufforderung haben können):

Prompt and nothing selected row

Verwendung im obigen Beispiel

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...]" />

NothingSelectedSpinnerAdapter.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.
    }

}
283
aaronvargas

Am Ende habe ich stattdessen eine Button verwendet. Während eine Button keine Spinner ist, lässt sich das Verhalten leicht anpassen.

Erstellen Sie zuerst den Adapter wie gewohnt:

String[] items = new String[] {"One", "Two", "Three"};
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
        Android.R.layout.simple_spinner_dropdown_item, items);

Beachten Sie, dass ich simple_spinner_dropdown_item als Layout-ID verwende. Auf diese Weise können Sie beim Erstellen des Alert-Dialogfelds ein besseres Aussehen erzielen.

Im onClick-Handler für meinen Button habe ich:

public void onClick(View w) {
  new AlertDialog.Builder(this)
  .setTitle("the Prompt")
  .setAdapter(adapter, new DialogInterface.OnClickListener() {

    @Override
    public void onClick(DialogInterface dialog, int which) {

      // TODO: user specific action

      dialog.dismiss();
    }
  }).create().show();
}

Und das ist es!

126
HRJ

Ich weiß, dass diese Frage viel Antwort hat, aber ich fand den einfachsten und einfachsten Weg.

Diese Lösung ist unabhängig von der API-Ebene und funktioniert für alle API-Ebenen.

Die Idee ist, das letzte Element des Spinners als Standardelement festzulegen 

spinner.setSelection(lastIndex);//index starts from 0.so if spinner has 5 item the lastIndex is 4

Der letzte Index sollte der Titel Ihres Spinners sein wie "Select Country".

Und während Sie den Drehbeschleuniger füllen, verringern Sie die Anzahl der Elemente um eins. Der Gesamtbetrag beginnt mit 1.

@Override
public int getCount() {
   // don't display last item. It is used as hint.
   int count = super.getCount();
   return count > 0 ? count - 1 : count;
}

So wird Ihr Code-Fluss so sein

List<String> objects = new ArrayList<String>();
objects.add("India");
objects.add("Pakistan");
objects.add("China");
// add hint as last item
objects.add("Select Country");

HintAdapter adapter = new HintAdapter(context, objects, Android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(Android.R.layout.simple_spinner_dropdown_item);

Spinner spinnerFilmType = (Spinner) findViewById(R.id.spinner);
spinner.setAdapter(adapter);

// show hint
spinner.setSelection(adapter.getCount());

HintAdapter.Java

public class HintAdapter extends ArrayAdapter<Objects> {

    public HintAdapter(Context theContext, List<Object> objects, int theLayoutResId) {
        super(theContext, theLayoutResId, objects);
    }

    @Override
    public int getCount() {
        // don't display last item. It is used as hint.
        int count = super.getCount();
        return count > 0 ? count - 1 : count;
    }
}

Spinner-Titel

 Spinner Title

Spinner-Artikel

 Spinner Items

100
Shakeeb Ayaz

Zunächst interessieren Sie vielleicht das Prompt-Attribut der Spinner-Klasse. Siehe das Bild unten, "Choose a Planet" ist die Eingabeaufforderung, die im XML mit Android:Prompt="" festgelegt werden kann.

 enter image description here

Ich wollte die Unterklasse Spinner vorschlagen, bei der Sie zwei Adapter intern verwalten können. Ein Adapter, der über die Option "Select One" verfügt, und der andere real - Adapter (mit den tatsächlichen Optionen). Anschließend können Sie die Adapter mit der Variablen OnClickListener wechseln, bevor der Auswahldialog angezeigt wird. Nach dem Versuch, diese Idee umzusetzen, bin ich zu dem Schluss gekommen, dass Sie keine OnClick-Ereignisse für das Widget selbst empfangen können.

Sie könnten den Spinner in eine andere Ansicht einwickeln, die Klicks in der Ansicht abfangen und dann Ihrer CustomSpinner sagen, dass sie den Adapter wechseln soll, aber es scheint ein schrecklicher Hack zu sein.

Müssen Sie wirklich "Select One" anzeigen? 

66
Casey

Dieser Code wurde getestet und funktioniert auf Android 4.4

enter image description here

Spinner spinner = (Spinner) activity.findViewById(R.id.spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(activity, Android.R.layout.simple_spinner_dropdown_item) {

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {

                View v = super.getView(position, convertView, parent);
                if (position == getCount()) {
                    ((TextView)v.findViewById(Android.R.id.text1)).setText("");
                    ((TextView)v.findViewById(Android.R.id.text1)).setHint(getItem(getCount())); //"Hint to be displayed"
                }

                return v;
            }       

            @Override
            public int getCount() {
                return super.getCount()-1; // you dont display last item. It is used as hint.
            }

        };

        adapter.setDropDownViewResource(Android.R.layout.simple_spinner_dropdown_item);
        adapter.add("Daily");
        adapter.add("Two Days");
        adapter.add("Weekly");
        adapter.add("Monthly");
        adapter.add("Three Months");
        adapter.add("HINT_TEXT_HERE"); //This is the text that will be displayed as hint.


        spinner.setAdapter(adapter);
        spinner.setSelection(adapter.getCount()); //set the hint the default selection so it appears on launch.
        spinner.setOnItemSelectedListener(this);
53
Manos

Ich habe diese Lösung gefunden:

String[] items = new String[] {"Select One", "Two", "Three"};
Spinner spinner = (Spinner) findViewById(R.id.mySpinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
            Android.R.layout.simple_spinner_item, items);
adapter.setDropDownViewResource(Android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);

spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {
        items[0] = "One";
        selectedItem = items[position];
    }

    @Override
    public void onNothingSelected(AdapterView<?> arg0) {
    }
});

Ändern Sie einfach das Array [0] mit "Select One" und benennen Sie es anschließend in onItemSelected in "One" um.

Keine klasse Lösung, aber es funktioniert: D

30

Es gibt keine Standard-API, um einen Hinweis für Spinner festzulegen. Um es hinzuzufügen, benötigen wir eine kleine Problemumgehung, ohne die Implementierung der Sicherheitsreflektion

List<Object> objects = new ArrayList<Object>();
objects.add(firstItem);
objects.add(secondItem);
// add hint as last item
objects.add(hint);

HintAdapter adapter = new HintAdapter(context, objects, Android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(Android.R.layout.simple_spinner_dropdown_item);

Spinner spinnerFilmType = (Spinner) findViewById(R.id.spinner);
spinner.setAdapter(adapter);

// show hint
spinner.setSelection(adapter.getCount());

Adapterquelle: 

public class HintAdapter
        extends ArrayAdapter<Objects> {

    public HintAdapter(Context theContext, List<Object> objects) {
        super(theContext, Android.R.id.text1, Android.R.id.text1, objects);
    }

    public HintAdapter(Context theContext, List<Object> objects, int theLayoutResId) {
        super(theContext, theLayoutResId, Android.R.id.text1, objects);
    }

    @Override
    public int getCount() {
        // don't display last item. It is used as hint.
        int count = super.getCount();
        return count > 0 ? count - 1 : count;
    }
}

Originalquelle

19
Yakiv Mospan

Viele Antworten, aber ich bin überrascht, dass niemand eine einfache Lösung vorgeschlagen hat: Platzieren Sie eine Textansicht auf dem Spinner. Legen Sie einen Click-Listener in der TextView fest, der die TextView-Ansicht des Spinner verbirgt und spinner.performClick () aufruft.

13
mjancola

Ich hatte das gleiche Problem für Spinner, mit einer leeren Auswahl, und ich fand eine bessere Lösung. Schauen Sie sich diesen einfachen Code an.

Spinner lCreditOrDebit = (Spinner)lCardPayView.findViewById(R.id.CARD_TYPE);
spinneradapter lAdapter = 
  new spinneradapter(
    BillPayScreen.this, 
    ndroid.R.layout.simple_spinner_item,getResources().getStringArray(R.array.creditordebit));
lAdapter.setDropDownViewResource(Android.R.layout.simple_spinner_dropdown_item);
lCreditOrDebit.setAdapter(lAdapter);

Hier ist Spinneradapter eine kleine Anpassung für Arrayadapter. Es sieht aus wie das:

import Android.content.Context;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.ArrayAdapter;
import Android.widget.ImageView;

public class spinneradapter extends ArrayAdapter<String>{
    private Context m_cContext;
    public spinneradapter(Context context,int textViewResourceId, String[] objects) {
        super(context, textViewResourceId, objects);
        this.m_cContext = context;
    }

    boolean firsttime = true;
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(firsttime){
            firsttime = false;
            //Just return some empty view
            return new ImageView(m_cContext);
        }
        //Let the array adapter take care of it this time.
        return super.getView(position, convertView, parent);
    }
}
9
Rajasekhar

XML-Datei: 

<Spinner Android:id="@+id/locationSpinner"
    Android:layout_width="fill_parent"
    Android:layout_height="wrap_content"
    Android:Prompt="@string/select_location" />

Aktivität:

private Spinner featuresSelection;
private ArrayAdapter<CharSequence> featuresAdapter;
private List<CharSequence> featuresList;

onCreate:

featuresList = new ArrayList<CharSequence>();
featuresAdapter = new ArrayAdapter<CharSequence>(this,
  Android.R.layout.simple_spinner_item, featuresList);
featuresAdapter.setDropDownViewResource(
  Android.R.layout.simple_spinner_dropdown_item);
featuresSelection = ((Spinner) yourActivity.this
  .findViewById(R.id.locationSpinner));
featuresSelection.setAdapter(featuresAdapter);
featuresSelection.setOnItemSelectedListener(
  new MyOnItemSelectedListener());

Einige Funktionen (programmgesteuert Dinge hinzufügen)>

featuresAdapter.add("some string");

Jetzt haben Sie einen leeren Spinner und Sie können Code schreiben, um den Dialog nicht zu öffnen, wenn er leer ist. Oder sie können zurückdrücken. Sie füllen es aber auch zur Laufzeit mit einer Funktion oder einer anderen Liste auf.

6
trgraglia

Sie können es in eine Textansicht umwandeln und diese verwenden:

Android:style="@Android:style/Widget.DeviceDefault.Light.Spinner"

und definieren Sie dann die Android:text-Eigenschaft.

6

Ich habe es wie folgt versucht. Nimm einen Button und gib das Click-Event dazu. Durch das Ändern des Schaltflächenhintergrunds scheint es sich um einen Spinner zu handeln.

Deklarieren Sie Alertdialog und Standardwert als globale Variablen.

AlertDialog d;
static int default_value = 0;
final Button btn = (Button) findViewById(R.id.button1);
btn .setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v)
{
    //c.show();
    final CharSequence str[] = {"Android","Black Berry","Iphone"};
        AlertDialog.Builder builder =
          new AlertDialog.Builder(TestGalleryActivity.this).setSingleChoiceItems(
            str, default_value,new  DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int position)
            {
                Toast.makeText(TestGalleryActivity.this,
                               "" + position,
                               Toast.LENGTH_SHORT).show();
                default_value = position;
                btn.setText(str[position]);
                if(d.isShowing())
                    d.dismiss();
            }
        }).setTitle("Select Any");
        d = builder.create();
        d.show();
    }
});
4
Ramesh Akula

Ich habe einen Spinner in meiner main.xml und die ID ist @+id/spinner1

folgendes schreibe ich in meine OnCreate-Funktion:

spinner1 = (Spinner)this.findViewById(R.id.spinner1);
final String[] groupes = new String[] {"A", "B", "C", "D", "E", "F", "G", "H"};
ArrayAdapter<CharSequence> featuresAdapter = new ArrayAdapter<CharSequence>(this, Android.R.layout.simple_spinner_item, new ArrayList<CharSequence>());
featuresAdapter.setDropDownViewResource(Android.R.layout.simple_spinner_dropdown_item);
spinner1.setAdapter(featuresAdapter);
for (String s : groupes) featuresAdapter.add(s);

spinner1.setOnItemSelectedListener(new OnItemSelectedListener() {
     public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id) {
         // Here go your instructions when the user chose something
         Toast.makeText(getBaseContext(), groupes[position], 0).show();
     }
     public void onNothingSelected(AdapterView<?> arg0) { }
});

Es ist keine Implementierung in der Klasse erforderlich.

3
Cyril

In der iosched-App finden Sie eine allgemeine Lösung zum Hinzufügen eines Elements am Anfang einer Liste. Wenn Sie einen CursorAdapter verwenden, sehen Sie sich insbesondere die Datei TracksAdapter.Java an, die diese Definition um eine "setHasAllItem" -Methode und den zugehörigen Code erweitert, um die Listenzahl zu verwalten, um das zusätzliche Element oben zu behandeln.

Mit dem benutzerdefinierten Adapter können Sie den Text auf "Select One" oder was auch immer Sie möchten, sagen.

3
Sport

Das ist mein Weg:

List<String> list = new ArrayList<String>();
list.add("string1");
list.add("string2");
list.add("string3");
list.add("[Select one]");
final int listsize = list.size() - 1;
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,Android.R.layout.simple_spinner_item, list) {
 @Override
public int getCount() {
    return(listsize); // Truncate the list
}
};
dataAdapter.setDropDownViewResource(Android.R.layout.simple_spinner_dropdown_item);
mySpinner.setAdapter(dataAdapter);

mySpinner.setSelection(listsize); // Hidden item to appear in the spinner
3
Cabezas

Ich denke, der einfachste Weg ist, ein Dummy-Element auf Index 0 zu erstellen, in dem "select one" ("auswählen") angezeigt wird, und beim Speichern vielleicht überprüfen, ob die Auswahl nicht 0 ist.

2
Tobias

Ich habe dafür viele gute Lösungen gefunden. Die meisten funktionieren, indem Sie ein Element am Ende des Adapters hinzufügen und nicht das letzte Element in der Dropdown-Liste anzeigen .. Das große Problem für mich war, dass die Dropdown-Liste des Spinners am Ende der Liste beginnt . Der Benutzer sieht also die letzten Elemente anstelle der ersten Elemente (falls viele Elemente angezeigt werden sollen), nachdem der Spinner zum ersten Mal berührt wurde.

Also stelle ich den Hinweis an den Anfang der Liste. und das erste Element in der Dropdown-Liste ausblenden.

private void loadSpinner(){

    HintArrayAdapter hintAdapter = new HintArrayAdapter<String>(context, 0);

    hintAdapter.add("Hint to be displayed");
    hintAdapter.add("Item 1");
    hintAdapter.add("Item 2");
            .
            .
    hintAdapter.add("Item 30");

    spinner1.setAdapter(hintAdapter);

    //spinner1.setSelection(0); //display hint. Actually you can ignore it, because the default is already 0
    //spinner1.setSelection(0, false); //use this if don't want to onItemClick called for the hint

    spinner1.setOnItemSelectedListener(yourListener);
}

private class HintArrayAdapter<T> extends ArrayAdapter<T> {

    Context mContext;

    public HintArrayAdapter(Context context, int resource) {
        super(context, resource);
        this.mContext = context
    }

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) {

        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(Android.R.layout.simple_spinner_item, parent, false);
        TextView texview = (TextView) view.findViewById(Android.R.id.text1);

        if(position == 0) {
            texview.setText("");
            texview.setHint(getItem(position).toString()); //"Hint to be displayed"
        } else {
            texview.setText(getItem(position).toString());
        }

        return view;
    }

    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent) {

        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        View view;

        if(position == 0){
            view = inflater.inflate(R.layout.spinner_hint_list_item_layout, parent, false); // Hide first row
        } else {
            view = inflater.inflate(Android.R.layout.simple_spinner_dropdown_item, parent, false);
            TextView texview = (TextView) view.findViewById(Android.R.id.text1);
            texview.setText(getItem(position).toString());
        } 

        return view;
    }
}

setzen Sie das folgende Layout in @Override getDropDownView (), wenn position 0 ist, um die erste Hinweiszeile auszublenden.

R.layout.spinner_hint_list_item_layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content" >

</LinearLayout>
2
Alireza Sobhani

Dies ist also mein letztes Beispiel "All-In" für einen Button-Spinner

In activity_my_form.xml

    <Button
        Android:id="@+id/btnSpinnerPlanets"
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:gravity="left|center_vertical"
        Android:singleLine="true"
        Android:text="@string/selectAPlanet"
        Android:textSize="10sp"
        Android:background="@Android:drawable/btn_dropdown">
    </Button>

In strings.xml

<string name="selectAPlanet">Select planet&#8230;</string>

<string-array name="planets__entries">
    <item>The Sun with a name very long so long long long long longThe Sun with a name very long so long long long long longThe Sun with a name very long so long long long long long</item>
    <item>Mercury</item>
    <item>Venus</item>
    <item>Earth</item>
    <item>Mars</item>
    <item>Jupiter</item>
    <item>Saturn</item>
    <item>Uranus</item>
    <item>Neptune</item>
</string-array>

In MyFormActivity.Java

public class MyFormActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        ((Button) findViewById(R.id.btnSpinnerPlanets)).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                final String[] items = view.getResources().getStringArray(R.array.planets__entries);
                ArrayAdapter<String> adapter = new ArrayAdapter<String>(MyFormActivity.this, Android.R.layout.simple_spinner_dropdown_item, items);
                new AlertDialog.Builder(MyFormActivity.this).setTitle("the Prompt").setAdapter(adapter, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ((Button) findViewById(R.id.btnSpinnerPlanets)).setText(items[which]);
                        dialog.dismiss();
                    }
                }).create().show();
            }
        });     

    }

}   

Schließlich erhielt ich eine konfigurierbare Schriftgröße, bei der kein erstes Element auswählbar ist. !!! Danke an HRJ

2
wildnove

Beim Erweitern von SpinnerAdapter überschreiben Sie zwei View-Produktionsmethoden, getView(int, View, ViewGroup) und getDropDownView(int, View, ViewGroup). Die erste liefert die View, die in die Spinner selbst eingefügt wurde. Die zweite liefert die Variable View in der Dropdown-Liste (wie der Name schon sagt). Sie können die getView(...) überschreiben, sodass bis zur Auswahl eines Elements eine TextView angezeigt wird, die eine Eingabeaufforderung enthält. Wenn Sie dann feststellen, dass ein Element ausgewählt wurde, ändern Sie es, um eine TextView anzuzeigen, die diesem entspricht.

public class PromptingAdapter extends SpinnerAdapter {

    //... various code ...

    private boolean selectionmade = false;

    //call this method from the OnItemSelectedListener for your Spinner
    public setSelectionState(boolean b) {
        selectionmade = b;
    }

    @Override
    public View getView(int position, View recycle, ViewGroup container) {
        if(selectionmade) {
            //your existing code to supply a View for the Spinner
            //you could even put "return getDropDownView(position, recycle, container);"
        }
        else {
            View output;
            if(recycle instanceof TextView) {
                 output = recycle;
            }
            else {
                 output = new TextView();
                 //and layout stuff
            }
            output.setText(R.string.please_select_one);
            //put a string "please_select_one" in res/values/strings.xml
            return output;
        }
    }

//...
}
1
Andrew Wyld

Für diejenigen, die Xamarin verwenden, ist hier das C # -Äquivalent zur Antwort von aaronvargas.

using Android.Content;
using Android.Database;
using Android.Views;
using Android.Widget;
using Java.Lang;

namespace MyNamespace.Droid
{ 
  public class NothingSelectedSpinnerAdapter : BaseAdapter, ISpinnerAdapter, IListAdapter
  {
    protected static readonly int EXTRA = 1;
    protected ISpinnerAdapter adapter;
    protected Context context;
    protected int nothingSelectedLayout;
    protected int nothingSelectedDropdownLayout;
    protected LayoutInflater layoutInflater;

    public NothingSelectedSpinnerAdapter(ISpinnerAdapter spinnerAdapter, int nothingSelectedLayout, Context context) : this(spinnerAdapter, nothingSelectedLayout, -1, context)
    {
    }

    public NothingSelectedSpinnerAdapter(ISpinnerAdapter spinnerAdapter, int nothingSelectedLayout, int nothingSelectedDropdownLayout, Context context)
    {
      this.adapter = spinnerAdapter;
      this.context = context;
      this.nothingSelectedLayout = nothingSelectedLayout;
      this.nothingSelectedDropdownLayout = nothingSelectedDropdownLayout;
      layoutInflater = LayoutInflater.From(context);
    }

    protected View GetNothingSelectedView(ViewGroup parent)
    {
      return layoutInflater.Inflate(nothingSelectedLayout, parent, false);
    }

    protected View GetNothingSelectedDropdownView(ViewGroup parent)
    {
      return layoutInflater.Inflate(nothingSelectedDropdownLayout, parent, false);
    }

    public override Object GetItem(int position)
    {
      return position == 0 ? null : adapter.GetItem(position - EXTRA);
    }

    public override long GetItemId(int position)
    {
      return position >= EXTRA ? adapter.GetItemId(position - EXTRA) : position - EXTRA;
    }

    public override 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);
      }

      // Could re-use the convertView if possible.
      return this.adapter.GetView(position - EXTRA, null, parent);
    }

    public override int Count
    {
      get
      {
        int count = this.adapter.Count;
        return count == 0 ? 0 : count + EXTRA;
      }
    }

    public override 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);
    }

    public override int GetItemViewType(int position)
    {
      return 0;
    }

    public override int ViewTypeCount => 1;

    public override bool HasStableIds => this.adapter.HasStableIds;

    public override bool IsEmpty => this.adapter.IsEmpty;

    public override void RegisterDataSetObserver(DataSetObserver observer)
    {
      adapter.RegisterDataSetObserver(observer);
    }

    public override void UnregisterDataSetObserver(DataSetObserver observer)
    {
      adapter.UnregisterDataSetObserver(observer);
    }

    public override bool AreAllItemsEnabled()
    {
      return false;
    }

    public override bool IsEnabled(int position)
    {
      return position > 0;
    }
  }
}
1
MPavlak

Ich habe dieses Problem auch mit dem folgenden Code gelöst. Angenommen, Sie haben eine Liste mit Elementen, z. 

ArrayList<Item> itemsArrayList = new ArrayList<Item>();
Item item1 = new Item();
item1.setId(1);
item1.setData("First Element");
Item item2 = new Item();
item2.setId(2);
Item2.setData("Second Element");
itemsArrayList.add(item1);
itemsArrayList.add(item2);

Jetzt müssen wir die Saiten dem Spinner zur Verfügung stellen, da der Spinner das Objekt nicht verstehen kann. Wir erstellen also eine neue Array-Liste mit String-Elementen wie diesem ->

ArrayList<String> itemStringArrayList = new ArrayList<String>();
for(Item item : itemsArrayList) {
    itemStringArrayList.add(item.getData());
}

Jetzt haben wir itemStringArrayList Array-Liste mit zwei String-Elementen. Als ersten Eintrag müssen wir den Text "Artikel auswählen" anzeigen. Wir müssen also eine neue Zeichenkette in itemStringArrayList einfügen.

itemStringArrayList.add("Select Item");

Jetzt haben wir eine Array-Liste itemsArrayList und wir möchten zwei Elemente in der Dropdown-Liste anzeigen. Die Bedingung hier ist jedoch: Wenn wir nichts auswählen, sollte Select Item als erstes Element erscheinen, das nicht aktiviert wird.

So können wir diese Funktionalität so implementieren. Wenn Sie die Array-Listenelemente in den Android-Spinner laden müssen. Sie müssen also einen Adapter verwenden. Also hier werde ich ArrayAdapter verwenden. Wir können den Adapter auch anpassen. 

ArrayAdapter<String> itemsArrayAdapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.spinner_item, itemsArrayList){
        @Override
        public boolean isEnabled(int position) {
            if(position == 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        @Override
        public View getDropDownView(int position, View convertView,
                                    ViewGroup parent) {
            View view = super.getDropDownView(position, convertView, parent);
            TextView tv = (TextView) view;
            if(position == 0){
                // Set the hint text color gray
                tv.setTextColor(Color.GRAY);
            }
            else {
                tv.setTextColor(Color.BLACK);
            }
            return view;
        }
    };

itemsArrayAdapter.setDropDownViewResource(R.layout.spinner_item);
your_spinner_name.setAdapter(itemsArrayAdapter);

Hier in diesem Code. Wir verwenden das angepasste Spinner-Layout, d. h. R.layout.spinner_item. Es ist eine einfache Textansicht 

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:padding="10dp"
    Android:textStyle="italic"
    Android:fontFamily="sans-serif-medium"
    />

Wir müssen den ersten Text im Spinner deaktivieren. Für die Position 0 deaktivieren wir also den Text. Und Farbe können wir auch einstellen, indem Sie die getDropDownView-Methode überschreiben. Auf diese Weise erhalten wir den erwarteten Spinner. 

1
Shravan Jain

Die beste Lösung, die ich dafür gefunden habe, besteht darin, nicht einen Spinner, sondern eine AutoCompleteTextView zu verwenden. Es ist im Grunde genommen ein EditText mit angefügtem Spinner, um Vorschläge während der Eingabe anzuzeigen - aber mit der richtigen Konfiguration kann es sich genau so verhalten, wie es sich das OP wünscht und mehr.

XML:

<com.google.Android.material.textfield.TextInputLayout
                Android:id="@+id/item"
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content">

            <androidx.appcompat.widget.AppCompatAutoCompleteTextView
                    Android:id="@+id/input"
                    Android:hint="Select one"
                    style="@style/AutoCompleteTextViewDropDown"/>
        </com.google.Android.material.textfield.TextInputLayout>

Stil:

<style name="AutoCompleteTextViewDropDown">
    <item name="Android:clickable">false</item>
    <item name="Android:cursorVisible">false</item>
    <item name="Android:focusable">false</item>
    <item name="Android:focusableInTouchMode">false</item>
    <item name="Android:layout_width">match_parent</item>
    <item name="Android:layout_height">wrap_content</item>
</style>

Verwenden Sie für den Adapter den grundlegenden ArrayAdapter oder erweitern Sie ihn, um Ihren eigenen zu erstellen. Es ist jedoch keine zusätzliche Anpassung auf der Adapterseite erforderlich. Stellen Sie den Adapter in der AutoCompleteTextView ein.

0
Chapz

um es einfach zu machen, einfach so:

String[] listAges = getResources().getStringArray(R.array.ages);

        // Creating adapter for spinner
        ArrayAdapter<String> dataAdapter =
                new ArrayAdapter<String>(this, Android.R.layout.simple_spinner_item, listAges);

        // Drop down layout style - list view with radio button
        dataAdapter.setDropDownViewResource(Android.R.layout.simple_spinner_dropdown_item);

        // attaching data adapter to spinner
        spinner_age.getBackground().setColorFilter(ContextCompat.getColor(this, R.color.spinner_icon), PorterDuff.Mode.SRC_ATOP);
        spinner_age.setAdapter(dataAdapter);
        spinner_age.setSelection(0);
        spinner_age.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String item = parent.getItemAtPosition(position).toString();

                if(position > 0){
                    // get spinner value
                    Toast.makeText(parent.getContext(), "Age..." + item, Toast.LENGTH_SHORT).show();
                }else{
                    // show toast select gender
                    Toast.makeText(parent.getContext(), "none" + item, Toast.LENGTH_SHORT).show();
                }
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
0
MrG
public AdapterView.OnItemSelectedListener instructorSpinnerListener = new AdapterView.OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView << ? > adapterView, View view, int i, long l) {
        String selectedInstructorName = adapterView.getItemAtPosition(i).toString();
        if (selectedInstructorName.equals("[Select Instructor]")) {
            instructorSpinnerAdapter.clear();
            for (Offering offering: allOfferingsList)
                instructorSpinnerAdapter.add(offering);
        } else {
            instructorSpinnerAdapter.clear();
        }
    }

    @Override
    public void onNothingSelected(AdapterView<< ? > adapterView) {
        adapterView.setSelection(0);

        // Toast.makeText(getApplicationContext(), "Why?", Toast.LENGTH_SHORT).show();
    }
};
0
Leace

Ich würde einfach eine Radiogruppe mit RadioButtons verwenden, wenn Sie nur drei Möglichkeiten haben, können Sie sie zunächst alle deaktivieren.

0
stephane k.

Außerdem gibt es einen einfachen Trick, um den Standard anzuzeigen:

Sie können einen Standardwert in Ihre Liste aufnehmen und dann mit list.addAll(yourCollection); Ihre gesamte Sammlung hinzufügen.

Funktionsfähiger Code hier:

List<FuelName> fuelList = new ArrayList<FuelName>();
                    fuelList.add(new FuelName(0,"Select One"));
                    fuelList.addAll(response.body());
                    ArrayAdapter adapter = new ArrayAdapter<>(getActivity(), Android.R.layout.simple_spinner_item, fuelList);
                    //fuelName.setPrompt("Select Fuel");
                    fuelName.setAdapter(adapter);

Hoffe, es wird deine Komplexität wiederherstellen. Viel Spaß beim Codieren!

0
Majedur Rahaman

für mich hat es so etwas geklappt. hat die Verbesserung, dass nur der Text in einigen Optionen geändert wird, nicht in allen.

Zuerst nehme ich die Namen des Spinners und erstelle den Arrayadapter mit einer benutzerdefinierten Ansicht, aber jetzt ist es egal, der Schlüssel überschreibt das getView und innerhalb von change ändern sich die Werte. In meinem Fall war es nur der erste, den Rest belasse ich das Original

public void rellenarSpinnerCompeticiones(){
        spinnerArrayCompeticiones = new ArrayList<String>();
        for(Competicion c: ((Controlador)getApplication()).getCompeticiones()){
            spinnerArrayCompeticiones.add(c.getNombre());
        }
        //ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(this,R.layout.spinner_item_competicion,spinnerArrayCompeticiones);
        ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(this, R.layout.spinner_item_competicion, spinnerArrayCompeticiones){
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                final View v = vi.inflate(R.layout.spinner_item_competicion, null);
                final TextView t = (TextView)v.findViewById(R.id.tvCompeticion);
                if(spinnerCompeticion.getSelectedItemPosition()>0){
                    t.setText(spinnerArrayCompeticiones.get(spinnerCompeticion.getSelectedItemPosition()));
                }else{
                    t.setText("Competiciones");
                }
                return v;
            }
        };
        spinnerArrayAdapter.setDropDownViewResource(Android.R.layout.simple_spinner_dropdown_item);
        spinnerCompeticion.setAdapter(spinnerArrayAdapter);
    }
0
Rako

hier ist eine einfache

    private boolean isFirst = true;
private void setAdapter() {
    final ArrayList<String> spinnerArray = new ArrayList<String>();     
    spinnerArray.add("Select your option");
    spinnerArray.add("Option 1");
    spinnerArray.add("Option 2");
    spin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
            TextView tv = (TextView)selectedItemView;
            String res = tv.getText().toString().trim();
            if (res.equals("Option 1")) {
            //do Something
        } else if (res.equals("Option 2")) {
            //do Something else
        }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parentView) { }

    });

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.my_spinner_style,spinnerArray) {
         public View getView(int position, View convertView, ViewGroup parent) {
             View v = super.getView(position, convertView, parent);
             int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 25, getResources().getDisplayMetrics());                  
             ((TextView) v).setTypeface(tf2);
             ((TextView) v).getLayoutParams().height = height;
             ((TextView) v).setGravity(Gravity.CENTER);
             ((TextView) v).setTextSize(TypedValue.COMPLEX_UNIT_SP, 19);
             ((TextView) v).setTextColor(Color.WHITE);
             return v;
         }

         public View getDropDownView(int position, View convertView,
                 ViewGroup parent) {
             if (isFirst) {
                 isFirst = false;
                 spinnerArray.remove(0);
             }
             View v = super.getDropDownView(position, convertView, parent);                  
             ((TextView) v).setTextColor(Color.argb(255, 70, 70, 70));
             ((TextView) v).setTypeface(tf2);
             ((TextView) v).setGravity(Gravity.CENTER);
             return v;
         }
     };
     spin.setAdapter(adapter);
}
0
Sayka

Siehe eine der obigen Antworten: https://stackoverflow.com/a/23005376/1312796

Ich habe meinen Code hinzugefügt, um einen kleinen Fehler zu beheben. Das, wo keine Daten abgerufen wurden .. Wie zeigt man den Prompt-Text an ...! 

Hier ist mein Trick ... Es funktioniert gut mit mir. ! 

Versuchen Sie, Ihren Spinner in ein relatives Layout zu setzen, und richten Sie eine Textansicht an Ihren Spinner aus. Spielen Sie mit der Sichtbarkeit der Textansicht (SHOW/HIDE), wenn der Adapter des Spinners geladen oder leer ist. 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_marginLeft="10dp"
Android:layout_marginRight="10dp"
Android:layout_marginTop="20dp"
Android:background="#ededed"
Android:orientation="vertical">



    <TextView
        Android:id="@+id/txt_Prompt_from"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_centerVertical="true"
        Android:textColor="@color/gray"
        Android:textSize="16sp"
        Android:layout_alignStart="@+id/sp_from"
        Android:text="From"
        Android:visibility="gone"/>

    <Spinner
        Android:id="@+id/sp_from"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_centerVertical="true"
        />

Hier ist der Code:

  txt__from = (TextView) rootView.findViewById(R.id.txt_Prompt_from);

rufen Sie diese Methode auf, nachdem der Spinneradapter geladen und leer war. 

setPromptTextViewVisibility (); //True or fales 

public void setPromptTextViewVisibility (boolean visible )
{
    if (visible)
    {
        txt_from.setVisibility(View.VISIBLE);
    }
    else
    {
        txt_from.setVisibility(View.INVISIBLE);
    }

}
0

Ich war gestern mit demselben Problem konfrontiert und wollte dem ArrayAdapter kein ausgeblendetes Element hinzufügen oder Spiegelungen verwenden, was gut funktioniert, aber irgendwie schmutzig ist.

Nachdem ich viele Beiträge gelesen und versucht hatte, fand ich eine Lösung, indem ich ArrayAdapter erweiterte und die getView -Methode überschreibe.

import Android.content.Context;
import Android.support.annotation.NonNull;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.ArrayAdapter;
import Android.widget.Spinner;
import Android.widget.TextView;

/**
 * A SpinnerAdapter which does not show the value of the initial selection initially,
 * but an initialText.
 * To use the spinner with initial selection instead call notifyDataSetChanged().
 */
public class SpinnerAdapterWithInitialText<T> extends ArrayAdapter<T> {

    private Context context;
    private int resource;

    private boolean initialTextWasShown = false;
    private String initialText = "Please select";

    /**
     * Constructor
     *
     * @param context The current context.
     * @param resource The resource ID for a layout file containing a TextView to use when
     *                 instantiating views.
     * @param objects The objects to represent in the ListView.
     */
    public SpinnerAdapterWithInitialText(@NonNull Context context, int resource, @NonNull T[] objects) {
        super(context, resource, objects);
        this.context = context;
        this.resource = resource;
    }

    /**
     * Returns whether the user has selected a spinner item, or if still the initial text is shown.
     * @param spinner The spinner the SpinnerAdapterWithInitialText is assigned to.
     * @return true if the user has selected a spinner item, false if not.
     */
    public boolean selectionMade(Spinner spinner) {
        return !((TextView)spinner.getSelectedView()).getText().toString().equals(initialText);
    }

    /**
     * Returns a TextView with the initialText the first time getView is called.
     * So the Spinner has an initialText which does not represent the selected item.
     * To use the spinner with initial selection instead call notifyDataSetChanged(),
     * after assigning the SpinnerAdapterWithInitialText.
     */
    @Override
    public View getView(int position, View recycle, ViewGroup container) {
        if(initialTextWasShown) {
            return super.getView(position, recycle, container);
        } else {
            initialTextWasShown = true;
            LayoutInflater inflater = LayoutInflater.from(context);
            final View view = inflater.inflate(resource, container, false);

            ((TextView) view).setText(initialText);

            return view;
        }
    }
}

Was Android beim Initialisieren des Spinners tut, ist der Aufruf von getView für das ausgewählte Element, bevor getView für alle Elemente in T[] objects..__ aufgerufen wird. Die Option SpinnerAdapterWithInitialText gibt eine TextView mit der initialText zurück Zeit, zu der es aufgerufen wird . Alle anderen Male ruft es super.getView auf. Dies ist die getView Methode von ArrayAdapter, die aufgerufen wird, wenn Sie den Spinner normalerweise verwenden.

Um herauszufinden, ob der Benutzer ein Spinnerelement ausgewählt hat oder wenn der Spinner noch die Option initialText anzeigt, rufen Sie selectionMade auf und übergeben Sie den Spinner, dem der Adapter zugewiesen ist.

0
pfaehlfd

Scheint eine banale Lösung zu sein, aber ich lege normalerweise einfach eine Textansicht in die Vorderseite des Spinners. Die ganze XML sieht so aus. (Hey Leute, erschießt mich nicht, ich weiß, dass einige von euch diese Art von Ehe nicht mögen):

<FrameLayout
    Android:id="@+id/selectTypesLinear"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="horizontal" >

    <Spinner
        Android:id="@+id/spinnerExercises"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:entries="@array/exercise_spinner_entries"
        Android:Prompt="@string/exercise_spinner_Prompt"
     />                         
    <TextView
        Android:id="@+id/spinnerSelectText"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:text="Hey! Select this guy!"
        Android:gravity="center"
        Android:background="#FF000000" />


</FrameLayout>

Dann blende ich die Textansicht aus, wenn ein Element ausgewählt wurde. Offensichtlich sollte die Hintergrundfarbe des TextView der des Spinners entsprechen. Funktioniert auf Android 4.0. Weiß nicht auf ältere Versionen.

Ja. Da der Spinner zu Beginn setOnItemSelectedListener aufruft, könnte das Ausblenden der Textansicht etwas schwierig sein, kann jedoch auf folgende Weise durchgeführt werden:

    Boolean controlTouched;

    exerciseSpinner.setOnTouchListener(new OnTouchListener() {


        @Override
        public boolean onTouch(View v, MotionEvent event) {
            controlTouched = true; // I touched it but but not yet selected an Item.
            return false;
        }

    });
    exerciseSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {

        @Override
        public void onItemSelected(AdapterView<?> arg0, View arg1,
                int arg2, long arg3) {
            if (controlTouched) { // Are you sure that I touched it with my fingers and not someone else  ?
                spinnerSelText.setVisibility(View.GONE);
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) {
        }

    });
0
Claudio Ferraro

Ich gehe damit um, indem ich einen Knopf anstelle eines Spinners benutze. Ich habe das Beispielprojekt auf GitHub.

Im Projekt zeige ich sowohl den Spinner als auch die Schaltfläche, um zu zeigen, dass sie tatsächlich identisch aussehen. Mit Ausnahme der Schaltfläche können Sie den Ausgangstext beliebig festlegen. 

So sieht die Aktivität aus:

package com.stevebergamini.spinnerbutton;

import Android.app.Activity;
import Android.app.AlertDialog;
import Android.content.DialogInterface;
import Android.os.Bundle;
import Android.view.View;
import Android.view.View.OnClickListener;
import Android.widget.Button;
import Android.widget.Spinner;

public class MainActivity extends Activity {

    Spinner spinner1;
    Button button1;
    AlertDialog ad;
    String[] countries;

    int selected = -1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        spinner1 = (Spinner) findViewById(R.id.spinner1);
        button1 = (Button) findViewById(R.id.button1);

        countries = getResources().getStringArray(R.array.country_names);

        //  You can also use an adapter for the allert dialog if you'd like
        //  ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, Android.R.layout.simple_spinner_dropdown_item, countries);        

        ad = new AlertDialog.Builder(MainActivity.this).setSingleChoiceItems(countries, selected,  
                new  DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            button1.setText(countries[which]);
                            selected = which;
                            ad.dismiss();

                        }}).setTitle(R.string.select_country).create(); 


        button1.setOnClickListener( new OnClickListener(){

            @Override
            public void onClick(View v) {
                ad.getListView().setSelection(selected);
                ad.show();              
            }});

    }

}

HINWEIS: Ja, mir ist klar, dass dies vom angewendeten Theme abhängt und das Aussehen bei der Verwendung von Theme.Holo etwas anders ist. Wenn Sie jedoch eines der alten Themen wie Theme.Black verwenden, können Sie loslegen.

0
SBerg413

Keine der zuvor eingereichten Antworten funktionierte wirklich so, wie ich dieses Problem lösen wollte. Für mich wäre die ideale Lösung, wenn der Spinner zum ersten Mal angezeigt wird. Wenn der Benutzer auf den Spinner tippt, sollte der Ausgangstext nicht Teil des angezeigten Dropdown-Menüs sein.

Um meine spezielle Situation weiter zu komplizieren, werden meine Spinner-Daten von einem Cursor erzeugt, der über die LoaderManager-Rückrufe geladen wird.

Nach langem Experimentieren kam ich zu folgender Lösung:

public class MyFragment extends Fragment implements
LoaderManager.LoaderCallbacks<Cursor>{

private static final String SPINNER_INIT_VALUE = "Select A Widget";
private Spinner mSpinner;
private int mSpinnerPosition;
private boolean mSpinnerDropDownShowing = false;
private View mSpinnerDropDown;

private MyCursorAdapter mCursorAdapter;

...

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
...

mCursorAdapter = new MyCursorAdapter(getActivity());

mSpinner = (Spinner) rootView.findViewById(R.id.theSpinner);
mSpinner.setOnTouchListener(mSpinnerTouchListener);
mSpinner.setAdapter(mCursorAdapter);

...
}

//Capture the touch events to toggle the spinner's dropdown visibility
private OnTouchListener mSpinnerTouchListener = new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if(mSpinnerDropDown != null && mSpinnerDropDownShowing == false){
            mSpinnerDropDownShowing = true;
            mSpinnerDropDown.setVisibility(View.VISIBLE);
        }
        return false;
    }
};

//Capture the click event on the spinner drop down items
protected OnClickListener spinnerItemClick = new OnClickListener(){

    @Override
    public void onClick(View view) {
        String widget = ((TextView) view.findViewById(Android.R.id.text1)).getText().toString();

        if(!widget.equals(SPINNER_INIT_VALUE)){
            if(mCursorAdapter != null){
                Cursor cursor = mCursorAdapter.getCursor();
                if(cursor.moveToFirst()){
                    while(!cursor.isAfterLast()){
                        if(widget.equals(cursor.getString(WidgetQuery.WIDGET_NAME))){

                            ...

                            //Set the spinner to the correct item
                            mSpinnerPosition = cursor.getPosition() + 1;
                            mSpinner.setSelection(mSpinnerPosition);
                            break;
                        }
                        cursor.moveToNext();
                    }
                }
            }
        }

        //Hide the drop down. Not the most elegent solution but it is the only way I could hide/dismiss the drop down
        mSpinnerDropDown = view.getRootView();
        mSpinnerDropDownShowing = false;
        mSpinnerDropDown.setVisibility(View.GONE);
    }
};

private class MyCursorAdapter extends CursorAdapter {

    private final int DISPLACEMENT = 1;
    private final int DEFAULT_ITEM_ID = Integer.MAX_VALUE;

    private Activity mActivity;

    public MyCursorAdapter(Activity activity) {
            super(activity, null, false);
            mActivity = activity;
    }

    //When loading the regular views, inject the defualt item
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(position == 0){
            if(convertView == null){
                convertView = mActivity.getLayoutInflater().inflate(R.layout.list_item_widget, parent, false);
            }
            return getDefaultItem(convertView);
        }
        return super.getView(position - DISPLACEMENT, convertView, parent);
    }

    //When loading the drop down views, set the onClickListener for each view
    @Override
    public View getDropDownView(int position, View convertView, ViewGroup parent){
        View view = super.getDropDownView(position, convertView, parent);
        view.setOnClickListener(spinnerItemClick);
        return view;
    }

    //The special default item that is being injected
    private View getDefaultItem(View convertView){
        TextView text = (TextView) convertView.findViewById(Android.R.id.text1);
        text.setText(SPINNER_INIT_VALUE);
        return convertView;
    }

    @Override
    public long getItemId(int position) {
        if (position == 0) {
            return DEFAULT_ITEM_ID;
        }
        return super.getItemId(position - DISPLACEMENT);
    }

    @Override
    public boolean isEnabled(int position) {
        return position == 0 ? true : super.isEnabled(position - DISPLACEMENT);
    }

    @Override
    public int getViewTypeCount() {
        return super.getViewTypeCount() + DISPLACEMENT;
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 0) {
            return super.getViewTypeCount();
        }

        return super.getItemViewType(position - DISPLACEMENT);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        return mActivity.getLayoutInflater().inflate(R.layout.list_item_widget, parent, false);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor){

        if(cursor.isAfterLast()){
            return;
        }

        TextView text = (TextView) view.findViewById(Android.R.id.text1);
        String WidgetName = cursor.getString(WidgetQuery.WIDGET_NAME);
        text.setText(WidgetName);
    }
}
}
0
Jed

wenn Sie mit diesem Problem konfrontiert sind, wenn Ihre Artikel vom Datenbank-Cursor ausgefüllt werden,

die einfachste Lösung, die ich in this SO gefunden habe:

Verwenden Sie UNION in Ihrem Cursoradapter query und fügen Sie das zusätzliche Element mit der ID = -1 zum Abfrageergebnis hinzu, ohne es wirklich der Datenbank hinzuzufügen:

so etwas wie:

db.rawQuery ("SELECT iWorkerId als _id, nvLastName als Name FROM Worker w UNION SELECT -1 als _id, '' als Name", null);

wenn das Element -1 ist, ist es der Standardwert. Andernfalls Es ist eine Aufzeichnung aus der Tabelle.

0
dvrm