AutoCompleteTextView-Elementauswahl programmgesteuert

Lesezeit: 6 Minuten

Benutzeravatar von Hussein Yassine
Hussein Jassine

ich habe ein AutoCompleteTextView die mit Städten aus einer SQLite-Datenbank gefüllt ist, die eine aufruft AsyncTask Beim Klicken auf einen Gegenstand habe ich kürzlich eine Option hinzugefügt, um meinen Standort mithilfe des GPS zu ermitteln. Das Problem ist also, dass ich die Stadt (z. B. Beirut) erkennen und den Text für die festlegen kann AutoCompleteTextView Aber die Sache ist die, dass sich der Dropdown-Filter öffnet und Beirut anzeigt (was richtig ist), aber ich muss immer noch auf das Listenelement klicken, um den Listener aufzurufen, wie man das programmgesteuert macht

Wie man:

  • Geben Sie die Aktivität ein (FERTIG)
  • Standort erkennen (FERTIG)
  • Text der Textansicht festlegen (FERTIG)
  • Textansicht-Dropdown-Liste anzeigen (FERTIG)
  • Wählen Sie den Artikel aus, der zurückgegeben werden soll, da er nur eine Stadt zurückgibt (NICHT FERTIG)

Benutzeravatar von JHowzer
JHowzer

Um es klarzustellen, Tano’s Lösung reicht aus, um diese Frage zu beantworten. Aber für den Fall, dass andere auf denselben Anwendungsfall stoßen wie ich, finden Sie hier weitere Hintergrundinformationen, die Ihnen möglicherweise helfen können …

Ich war speziell auf dieses Problem gestoßen, als ich versuchte, eine nicht bearbeitbare Datei zu erstellen Dropdown-Menü „Material ausgesetzt“. und setzen Sie den Anfangswert programmgesteuert. Die Dokumentation zum Erstellen dieser Art von “Dropdown” finden Sie im Abschnitt Verfügbare Dropdown-Menüs hierwas auf einen Mechanismus hindeutet, der verwendet TextInputLayout und AutocompleteTextView (auch wenn Sie keine Autocomplete-Funktionalität wünschen).

Fehlgeschlagene Lösung 1:
Auf den ersten Blick setListSelection() und getListSelection() schien, als könnten sie den Trick machen. Aber nach vielen Versuchen habe ich gelernt, dass sie möglicherweise nicht ausreichen, weil sie nur funktionieren, wenn das Listen-Popup angezeigt wird isShowing(). Wenn Sie also zum Beispiel einfach die Anfangsauswahl setzen möchten, ohne zuerst das Listen-Popup anzeigen zu müssen, wird dies nicht funktionieren.

Fehlgeschlagene Lösung 2:
Dann habe ich es versucht setText() was den richtigen Text in meinem Textfeld zeigte. Yay! Aber warte! Als ich auf die Textansicht klickte, wurde aus irgendeinem Grund nur eine Teilmenge der Optionen im Listen-Popup angezeigt. Warum war das? Das Wichtigste, was Sie hier beachten sollten, ist, dass dies eine ist Autovervollständigung textview, standardmäßig Filter out-Optionen basierend auf dem Text in der Textansicht. Dies ist möglicherweise nicht offensichtlich, insbesondere wenn Sie dieses Steuerelement nur verwenden, um eine einfache, nicht bearbeitbare Dropdown-Auswahl zu erstellen.

Lösung:
Dies bringt uns zu unserer eigentlichen Lösung (vorgeschlagen von Tano) … setText() mit filter wie false schaltet die Filterfunktionen aus UND ändert den Inhalt Ihres Listen-Popups nicht.

autoCompleteTextView.setText(myText, false);

  • Ich versuche auch, die Autocomplete-Textansicht zu verwenden, um ein nettes Dropdown-Menü zu erstellen, das sich wie ein Spinner verhält (abzüglich der nervigen Listener, die ausgelöst werden, aber mit dem netten umrissenen Aussehen, das das Textinputlayout bietet). Die Lösungen hier funktionieren, um das ausgewählte Element basierend auf Text festzulegen, aber ich möchte alle verfügbaren Optionen, wenn Sie die automatische Vervollständigung berühren. Im Moment müsste ich den Text noch löschen, damit alle erscheinen. Irgendwelche Ideen? Oder gibt es eine Möglichkeit, einen Spinner wie das umrissene Texteingabelayout aussehen zu lassen?

    – JPM

    26. Juli 2019 um 2:02 Uhr

  • Dies ist eine brillante Antwort und gut erklärt. Das einzige Problem, das ich habe, ist, dass die Filteroption ein API-Level von 17 erfordert

    – dave o grady

    3. März 2020 um 0:41 Uhr

  • @JPM, Sie können jederzeit eine Dropdown-Liste anzeigen, siehe stackoverflow.com/a/26036902/2914140. Derzeit wird (erstmals) eine vollständige Liste geöffnet, auch wenn Text eingegeben wurde. Wenn Sie einen Text bearbeiten, werden Elemente gefiltert. Vielleicht funktioniert stackoverflow.com/a/60791879/2914140, habe es nicht überprüft.

    – CoolMind

    2. Juni 2020 um 12:39 Uhr


  • Ich habe ein paar Stunden mit den hier erwähnten gescheiterten Lösungen verbracht, und jetzt stehe ich so kurz vor einer beruflichen Veränderung, nachdem ich 8 Jahre lang Android-Apps entwickelt habe.

    – SafaOrhan

    1. Oktober 2021 um 15:25 Uhr


Tanos Benutzeravatar
Tano

Ich stand vor einem ähnlichen Problem und dies löste mein Problem. Wichtig ist anzurufen setText(<text>, <filter boolean>) Um nicht mit dem angegebenen Text zu filtern, setzen Sie den zweiten Parameter mit false. Der Text wird aus dem Dropdown-Adapter geholt.

Lösungsausschnitt:

automCompleteTextView.setText(automCompleteTextView.getAdapter().getItem(position).toString(), false);

  • Vielen Dank! Ich finde, false ist ein Standardwert. Also können wir verwenden autoCompleteTextView.setText(someText);.

    – CoolMind

    2. Juni 2020 um 13:01 Uhr

  • Funktioniert einwandfrei danke!

    – SCHMUTZIGER DAVE

    16. Januar um 9:59 Uhr

Eine Lösung, bei der Sie Ihr API-Level nicht ändern müssen.

automCompleteTextView.setAdapter(adapter);        
// set default selection, filtering is active so all items is not visible in drop-down menu
automCompleteTextView.setText(automCompleteTextView.getAdapter().getItem(0).toString());
// change filtering for the adapter so all items can be visible in drop-down menu
adapter.getFilter().filter(null);

Einzeiler für denselben Job, erfordert jedoch eine höhere API-Ebene

automCompleteTextView.setText(automCompleteTextView.getAdapter().getItem(0).toString(), false);

Ich finde heraus, nachdem ich mich mit dem AutoCompleteTextView-Code im Android-Quellcode befasst habe:

fun AutoCompleteTextView.selectItem(text: String, position: Int = 0) {
  this.setText(text)
  this.showDropDown()
  this.setSelection(position)
  this.listSelection = position
  this.performCompletion()
}

autoComplete.setListSelection(position);

  • Dadurch wird das Element nicht für mich ausgewählt, wenn die Liste nicht angezeigt wird

    – SCHMUTZIGER DAVE

    16. Januar um 9:57 Uhr

Ich habe benutzt autoCompleteTextView.setText(myText, false); auch eine Lösung, die jedoch manchmal fehlschlug. Ich meine, es wurden Ergebnisse aktiv gefiltert, sodass beim Klicken des Benutzers nur 1 Element im Dropdown angezeigt wurde.

Außerdem brauchte ich dies auch, um an benutzerdefinierten Objekten zu arbeiten, und das ist meine Lösung:

binding.hourEditText.configureDropDownMenu(viewModel.hours) { it.hourString() }
    .subscribe {
        // Do whatever you need when on click.
    }
    .addTo(disposables)

fun <T> AutoCompleteTextView.configureDropDownMenu(list: List<T>, toString: ((T) -> String)? = null): Observable<T> {
    keyListener = null
    val textItems = toString?.let(list::map) ?: list.map { it.toString() }
    setAdapter(NonFilterArrayAdapter(context!!, android.R.layout.simple_spinner_dropdown_item, textItems))
    return itemClickEvents().map {
        list[it.position]
    }
}

private class NonFilterArrayAdapter<T>(context: Context, @LayoutRes resource: Int, objects: List<T>) : ArrayAdapter<T>(context, resource, objects) {

    override fun getFilter() = NonFilter()

    private class NonFilter : Filter() {
        override fun performFiltering(constraint: CharSequence?) = FilterResults()

        override fun publishResults(constraint: CharSequence?, results: FilterResults?) = Unit
    }
}

Notiz: Dies enthält auch ein bisschen Rx, aber es kann leicht entfernt werden.

  • Dadurch wird das Element nicht für mich ausgewählt, wenn die Liste nicht angezeigt wird

    – SCHMUTZIGER DAVE

    16. Januar um 9:57 Uhr

Versuchen Sie, unten nach setText () in AutoCompleteTextview hinzuzufügen: –

autoCompleteTV.setSelection(position);

Aktualisiert:

Das wird einwirken Spinner und AutoCompleteTextView die Dropdown-Funktion hat, aber es wird nicht mit funktionieren EditText.

Hier können Sie Dokumente nachsehen AbsSpinner unter diesem Link:
https://developer.android.com/reference/android/widget/AbsSpinner.html#setSelection(int)

  • @HusseinYassine Lassen Sie mich meine Arbeit einchecken und werde mit der Lösung zurückkommen.

    – Nitin Patel

    7. Juli 2017 um 6:35 Uhr

  • setSelection ist eine Abkürzung dafür, wo der Cursor platziert werden soll, ohne ein Element im Adapter auszuwählen.

    – Chris.Jenkins

    18. August 2019 um 22:15 Uhr

  • @Chris.Jenkins Überprüfen Sie zur Klärung diesen Link developer.android.com/reference/android/widget/… und immer noch nicht bekommen, dann nach der Initialisierung einfach mal mit anderer Position probieren.

    – Nitin Patel

    19. August 2019 um 12:39 Uhr

  • @NitinPatel Ja, das ist für eine AbstractSpinner, AutoCompleteTextView ist das nicht. setSelection auf ein EditText legt die Cursorposition fest, nicht die Auswahl des Elements in einem Spinner.

    – Chris.Jenkins

    20. August 2019 um 14:01 Uhr


  • Dies kann zu einem Absturz führen: ‘java.lang.IndexOutOfBoundsException: setSpan (43 … 43) ended beyond length 34’. Verwenden setListSelection stattdessen.

    – CoolMind

    2. Juni 2020 um 13:44 Uhr


1394300cookie-checkAutoCompleteTextView-Elementauswahl programmgesteuert

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy