608 Stimmen

Wie erstellt man einen Android Spinner mit dem Anfangstext "Select One"?

Ich möchte einen Spinner verwenden, der zunächst (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 im Spinner anstelle von "Select One" 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);

Mit diesem Code wird zunächst das Element "Eins" angezeigt. Ich könnte einfach ein neues Element "Select One" zu den Elementen hinzufügen, aber dann würde "Select One" auch in der Dropdown-Liste als erstes Element angezeigt werden, was ich nicht möchte.

Wie kann ich dieses Problem beheben?

7 Stimmen

Die perfekte Lösung liegt in dieser Frage: stackoverflow.com/questions/9863378/ Überschreiben Sie einfach die Methode getDropDownView().

0 Stimmen

Haben Sie versucht, das erste Element Ihres Adapters auf "Select One" einzustellen?

0 Stimmen

[Hier eine andere tolle, schöne Lösung!][1] [1]: stackoverflow.com/questions/9863378/

0voto

SBerg413 Punkte 14276

Ich verwende dazu eine Schaltfläche anstelle eines Spinners. Ich habe das Beispielprojekt auf GitHub.

Im Projekt zeige ich sowohl den Spinner als auch die Schaltfläche an, um zu zeigen, dass sie tatsächlich identisch aussehen. Außer der Schaltfläche können Sie den anfänglichen Text auf was auch immer Sie wollen setzen.

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 verwendeten Theme abhängt und das Aussehen bei Verwendung von Theme.Holo etwas anders sein wird. Allerdings, wenn Sie eine der Legacy-Themen wie Theme.Black verwenden, sind Sie gut zu gehen.

0voto

Leace Punkte 262
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();
    }
};

0voto

Jed Punkte 7732

Keine der zuvor eingereichten Antworten hat wirklich so funktioniert, wie ich dieses Problem lösen wollte. Für mich wäre die ideale Lösung die "Select One" (oder was auch immer Anfangstext), wenn der Spinner zum ersten Mal angezeigt wird. Wenn der Benutzer auf den Spinner tippt, sollte der Anfangstext nicht Teil des angezeigten Dropdowns sein.

Um meine besondere Situation weiter zu erschweren, meine Spinner-Daten kommt aus einem Cursor, der über die LoaderManager Callbacks geladen wird.

Nach ausgiebigem Experimentieren bin ich auf die folgende Lösung gekommen:

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

0voto

stephane k. Punkte 1500

Ich würde einfach eine RadioGroup mit RadioButtons verwenden, wenn Sie nur drei Auswahlmöglichkeiten haben, können Sie sie alle zunächst nicht markieren.

-1voto

Manan Sharma Punkte 631

Nehmen wir an, es gibt N Positionen, die ausgewählt werden müssen.

Nach dem Hinzufügen dieser N Elemente fügen Sie den Hinweistext als (N+1)-tes Element hinzu.

Setzen Sie das ausgewählte Element an die N-te Position [(N+1)-tes Element].

In Ihrem OnItemSelected Listener, wenn die ausgewählte Position nicht N ist, pop das letzte Element und rufen Sie Adapter.notifyDataSetChanged() und setzen Sie ausgewählte Element als die ausgewählte Position.

Algo así:

    spinner.setItems("Daily", "One time", "Frequency"); // here "Frequency is the hint text"
    spinner.setSelectedIndex(2);

    spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
        @Override
        public void onItemSelected(Spinner view, int position, long id, Object item) {
            if (position != 2) {
                view.setItems("Daily", "One time");
                view.setSelectedIndex(position);
            }else {
                // This item is not a valid selection
            }
        }
    });

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X