AutoCompleteTextView item selection programmatically

前端 未结 9 2077
故里飘歌
故里飘歌 2021-02-18 14:41

I have an autocomplete text view that is filled with cities from an sqlite database that calls an async task on item click, recently I added an option to detect my location usin

相关标签:
9条回答
  • 2021-02-18 14:57

    A solution were you don't need to change your API level.

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

    one-liner for the same job but requires higher API level

    automCompleteTextView.setText(automCompleteTextView.getAdapter().getItem(0).toString(), false);
    
    0 讨论(0)
  • 2021-02-18 14:58

    Try with adding below after setText() in AutoCompleteTextview:-

    autoCompleteTV.setSelection(position);
    

    Updated:

    This will work in Spinner and AutoCompleteTextView which has dropdown feature, but it will not work with EditText.

    Here you can check docs for AbsSpinner in this link: https://developer.android.com/reference/android/widget/AbsSpinner.html#setSelection(int)

    0 讨论(0)
  • 2021-02-18 14:58

    I was facing a similar problem and this solved my issue. Important is to call setText(<text>, <filter boolean>) in order not to filter with the given text set the second parameter with false. The text will be got from the dropdown adapter.

    Solution snippet:

    automCompleteTextView.setText(automCompleteTextView.getAdapter().getItem(position).toString(), false);
    
    0 讨论(0)
  • 2021-02-18 15:02

    I figure out after dig into the AutoCompleteTextView code on android source code:

    fun AutoCompleteTextView.selectItem(text: String, position: Int = 0) {
      this.setText(text)
      this.showDropDown()
      this.setSelection(position)
      this.listSelection = position
      this.performCompletion()
    }
    
    0 讨论(0)
  • 2021-02-18 15:06

    I have used autoCompleteTextView.setText(myText, false); solution as well, however it sometimes failed. I mean it was actively filtering results so, when user clicks there was only 1 item at dropdown.

    In addition I also needed this to work on custom objects as well, and this is my my solution:

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

    Note: This also contains a bit of Rx, but it can be removed easily.

    0 讨论(0)
  • 2021-02-18 15:15

    To be clear, Tano's solution is sufficient to answer this question. But, in case others run into the same use case I did, here's some more background that may potentially help you...

    I had been running into this issue specifically while trying to make a non-editable Material Exposed Dropdown Menu and set it's initial value programmatically. The documentation to create this type of "dropdown" can be found in the Exposed Dropdown Menus section here, which suggests a mechanism using TextInputLayout and AutocompleteTextView (even if you don't want autocomplete functionality).

    Failed Solution 1: At first glance setListSelection() and getListSelection() seemed like they might do the trick. But after many trials, I learned that they may not be sufficient because they only work when the list popup isShowing(). So for example, if you simply want to set the initial selection without having to show the list popup first, this will not work.

    Failed Solution 2: Then I tried setText() which showed the proper text in my textbox. Yay! But wait! When I clicked on the text view, only a subset of options in the list popup were shown for some reason. Why was that? The key thing to keep in mind here is that since this is an autocomplete textview, it by default filters out options based off of the text in the textview. This might not be apparent, especially if you're solely using this control for the sake of making a simple non-editable dropdown selector.

    Solution: This brings us to our actual solution (suggested by Tano)... setText() with filter as false will turn off the filtering capabilities AND it will not change the contents of your list popup.

    autoCompleteTextView.setText(myText, false);
    
    0 讨论(0)
提交回复
热议问题