wake-up-neo.net

Festlegen eines Spinners onClickListener () in Android

Ich versuche, einen onClickListener auf einen Spinner abzufeuern, aber ich erhalte die folgende Fehlermeldung:

Java.lang.RuntimeException ist "Rufen Sie nicht setOnClickListener für eine AdapterView auf. Sie möchten wahrscheinlich stattdessen setOnItemClickListener."

Ich bin sicher, ich möchte onClickListener und NICHT onItemClickListener aufrufen. Ich habe eine Frage von jemand anderem zu Stack Overflow gefunden, Gibt es eine Möglichkeit, setOnClickListener mit einem Android-Spinner zu verwenden?

Die dort angegebene Antwort lautet:

Sie müssen den Click einstellen Listener für die zugrunde liegende Ansicht (normalerweise ein TextView mit der ID: Android.R.id.text1) des Spinners. Zu tun Sie dies:

Erstellen Sie einen benutzerdefinierten Spinner in der Konstruktor (mit Attributen) create der Spinner durch Angabe des Layouts Android.R.layout.simple_spinner_item Führen Sie eine findViewById (Android.R.id.text1) .__ aus. Um die Textansicht zu erhalten, stellen Sie jetzt die onClickListener auf die TextView

Ich habe die dort angegebene Antwort ausprobiert, aber es scheint nicht zu funktionieren. Ich bekomme einen Nullzeiger auf die TextView, nachdem ich findViewById () gemacht habe.

Das mache ich:

Spinner spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.layoutspinner,dataArray);

spinner.setAdapter(adapter);

TextView SpinnerText = (TextView)findViewById(R.id.spinnerText);
if (SpinnerText == null) {
    System.out.println("Not found");
}
else {
    SpinnerText.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {
            //Do something
        }
    });
}

Datei layoutspinner.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
                  Android:id="@+id/spinnerText"
                  Android:singleLine ="true"
                  Android:layout_width="fill_parent"
                  Android:layout_height="wrap_content"
                  Android:textSize="6pt"
                  Android:gravity="right"/>

Was mache ich falsch?

Ich bin neu bei Stack Overflow. Ich habe keine Möglichkeit gefunden, eine zusätzliche Frage an den anderen Thread zu senden (oder einen Kommentar, da ich zu wenig rep habe), also habe ich eine neue Frage gestellt.

Per Empfehlung habe ich folgendes versucht:

int a = spinnerMes.getCount();
int b = spinnerMes.getChildCount();
System.out.println("Count = " + a);
System.out.println("ChildCount = " + b);
for (int i = 0; i < b; i++) {
    View v = spinnerMes.getChildAt(i);
    if (v == null) {
        System.out.println("View not found");
    }
    else {
        v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Click code
            }
        });
    }
}

Aber LogCat zeigt keine vielversprechenden Ergebnisse.

10-14 16:09:08.127: INFO/System.out(3116): Count = 7
10-14 16:09:08.127: INFO/System.out(3116): ChildCount = 0

Ich habe dies auf den API-Stufen 7 und 8 mit den gleichen Ergebnissen getestet.

32
blindstuff

Folgendes funktioniert so, wie Sie es möchten, aber es ist nicht ideal.

public class Tester extends Activity {

    String[] vals = { "here", "are", "some", "values" };
    Spinner spinner;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        spinner = (Spinner) findViewById(R.id.spin);
        ArrayAdapter<String> ad = new ArrayAdapter<String>(this, Android.R.layout.simple_dropdown_item_1line, vals);
        spinner.setAdapter(ad);
        Log.i("", "" + spinner.getChildCount());
        Timer t = new Timer();
        t.schedule(new TimerTask() {

            @Override
            public void run() {
                int a = spinner.getCount();
                int b = spinner.getChildCount();
                System.out.println("Count =" + a);
                System.out.println("ChildCount =" + b);
                for (int i = 0; i < b; i++) {
                    View v = spinner.getChildAt(i);
                    if (v == null) {
                        System.out.println("View not found");
                    } else {
                        v.setOnClickListener(new View.OnClickListener() {

                            @Override
                            public void onClick(View v) {
                                        Log.i("","click");
                                        }
                        });
                    }
                }
            }
        }, 500);
    }
}

Sagen Sie mir genau, wie Sie den Spinner brauchen, und wir können eine bessere Lösung finden.

4
Dave.B

Hier ist eine funktionierende Lösung:

Anstatt den OnClickListener des Spinners einzustellen, setzen wir OnTouchListener und OnKeyListener.

spinner.setOnTouchListener(Spinner_OnTouch);
spinner.setOnKeyListener(Spinner_OnKey);

und die Zuhörer:

private View.OnTouchListener Spinner_OnTouch = new View.OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            doWhatYouWantHere();
        }
        return true;
    }
};
private static View.OnKeyListener Spinner_OnKey = new View.OnKeyListener() {
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            doWhatYouWantHere();
            return true;
        } else {
            return false;
        }
    }
};
55
OferR

Verwenden Sie die folgende Methode, wenn Sie beim Klick auf den Spinner eine Aktion ausführen müssen.

mspUserState.setOnTouchListener(new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            doWhatIsRequired();
        }
        return false;
    }
});

Eine Sache, die zu beachten ist, ist immer False zurückzugeben, während die obige Methode verwendet wird. Wenn Sie True zurückgeben, werden die Dropdown-Elemente des Spinners nicht angezeigt, wenn Sie auf den Spinner klicken.

25
Gaurav Arora

Ich persönlich benutze das:

    final Spinner spinner = (Spinner) (view.findViewById(R.id.userList));
    spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {                

            userSelectedIndex = position;
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {
        }
    });  
12
Lumi

Zunächst unterstützt ein Spinner keine Elementklickereignisse. Beim Aufruf dieser Methode wird eine Ausnahme ausgelöst.

Sie können setOnItemSelectedListener verwenden:

Spinner s1;
s1 = (Spinner)findViewById(R.id.s1);
int selectionCurrent = s1.getSelectedItemPosition();

spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
            if (selectionCurrent != position){
                // Your code here
            }
            selectionCurrent= position;
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parentView) {
        // Your code here
    }
});
5
sumit pandey

Ich schlage vor, dass alle Events für Spinner in zwei Arten unterteilt sind:

  1. Benutzerereignisse (Sie meinten als "Klick" -Ereignis).

  2. Programmereignisse.

Ich schlage auch vor, dass Sie, wenn Sie ein Benutzerereignis abfangen möchten, nur "Programmereignisse" loswerden möchten. Also ganz einfach:

private void setSelectionWithoutDispatch(Spinner spinner, int position) {
    AdapterView.OnItemSelectedListener onItemSelectedListener = spinner.getOnItemSelectedListener();
    spinner.setOnItemSelectedListener(null);
    spinner.setSelection(position, false);
    spinner.setOnItemSelectedListener(onItemSelectedListener);
}

Es gibt einen entscheidenden Moment: Sie benötigen setSelection (position, false). "false" im Animationsparameter löst das Ereignis sofort aus. Das Standardverhalten ist, Ereignis in Ereigniswarteschlange zu verschieben.

2
Slava

Die Spinner-Klasse implementiert DialogInterface.OnClickListener, wobei sie den Standard View.OnClickListener effektiv entführt.

Wenn Sie keinen Unterklassen-Spinner verwenden oder dies nicht beabsichtigen, wählen Sie eine andere Antwort. 

Ansonsten fügen Sie einfach folgenden Code zu Ihrem benutzerdefinierten Spinner hinzu:

@Override
/** Override triggered on 'tap' of closed Spinner */
public boolean performClick() {
    // [ Do anything you like here ]
    return super.performClick();
}

Beispiel: Zeigen Sie einen vordefinierten Hinweis über die Snackbar an, wenn der Spinner geöffnet wird: 

private String sbMsg=null;      // Message seen by user when Spinner is opened.
public void setSnackbarMessage(String msg) { sbMsg=msg; }
@Override
/** Override triggered on 'tap' of closed Spinner */
public boolean performClick() {
    if (sbMsg!=null && !sbMsg.isEmpty()) { /* issue Snackbar */ }
    return super.performClick();
}

 Trapping 'click' of closed Spinner

Ein benutzerdefinierter Spinner ist ein hervorragender Ausgangspunkt für die programmgesteuerte Standardisierung des Spinner-Erscheinungsbildes im gesamten Projekt.

Bei Interesse schau hier

0
Bad Loser