以编程方式选择AutoCompleteTextView项目

时间:2017-07-07 05:29:56

标签: android adapter autocompletetextview

我有一个自动填充文本视图,其中填充了sqlite数据库中的城市,在项目点击时调用异步任务,最近我添加了一个选项来使用gps检测我的位置,所以问题是我可以检测到城市(即贝鲁特)并设置autocompletetextview的文本,但问题是下拉过滤器打开显示贝鲁特(这是正确的),但我仍然需要点击列表项来调用监听器,如何以编程方式这样做

如何: 输入活动(完成) 检测位置(完成) 设置文本视图文本(完成) show textview下拉列表(DONE) 选择将要返回的项目,因为它只返回一个城市(未完成)

此致

9 个答案:

答案 0 :(得分:9)

您不需要更改API级别的解决方案。

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

同一工作但需要更高的API级别

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

答案 1 :(得分:2)

我在挖掘Android源代码中的AutoCompleteTextView代码后想出来:

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

答案 2 :(得分:1)

尝试在AutoCompleteTextview中的setText()之后添加以下内容: -

autoCompleteTV.setSelection(position);

答案 3 :(得分:1)

autoComplete.setListSelection(position);

答案 4 :(得分:1)

我也使用过 autoCompleteTextView.setText(myText, false); 解决方案,但有时会失败。我的意思是它正在主动过滤结果,所以当用户点击时,下拉菜单中只有 1 个项目。

此外,我还需要它来处理自定义对象,这是我的解决方案:

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

注意:这也包含一些 Rx,但可以轻松删除。

答案 5 :(得分:0)

问题是您正在设置文字,AutoCompleteTextView仅显示与该文字匹配的字词。解决此问题的一种非常优雅的方法是设置一个高阈值(至少是城市名称的最大长度),以强制Android显示列表的所有值(此阈值是该字段必须包含的字符数)必须搜索相似之处)。

答案 6 :(得分:0)

我遇到了类似的问题,这解决了我的问题。重要的是调用setText(,)以便不过滤给定的文本,而将第二个参数设置为 false 。文本将从下拉菜单适配器中获取

解决方案摘要:

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

答案 7 :(得分:0)

需要明确的是,塔诺的解决方案足以回答这个问题。但是,如果其他人遇到了与我相同的用例,这里有一些其他背景可能会帮助您...

我在尝试制作一个不可编辑的Material Exposed Dropdown Menu并以编程方式设置其初始值时遇到了这个问题。可以在“公开的下拉菜单”部分here中找到用于创建此类“下拉菜单”的文档,该文档建议了一种使用dat <- structure(c(0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1), .Dim = c(3L, 6L), .Dimnames = structure(list(c("Fund 1", "Fund2", "Fund3"), c("Firm A", "Firm B", "Firm C", "Firm D", "Firm E", "Firm F")), .Names = c("", "")), class = "table") TextInputLayout的机制(即使您不希望自动完成功能)。

失败的解决方案1: 乍看起来AutocompleteTextViewsetListSelection()似乎可以解决问题。但是经过多次试验,我了解到它们可能还不够,因为它们仅在列表弹出getListSelection()时才起作用。因此,例如,如果您只想设置初始选择而不必先显示列表弹出窗口,则此方法将无效。

解决方案2失败: 然后,我尝试了isShowing(),该文本在我的文本框中显示了正确的文本。好极了!可是等等!当我单击文本视图时,由于某种原因,列表弹出窗口中仅显示选项的子集。怎么会这样这里要记住的关键是,由于这是自动完成文本视图,因此默认情况下,它会根据文本视图中的文本过滤选项。这可能并不明显,尤其是如果您只是为了制作一个简单的不可编辑的下拉选择器而仅使用此控件时。

解决方案: 这将我们带入实际的解决方案(由Tano建议)... setText()setText()一起使用,因为filter将关闭过滤功能,并且不会更改列表弹出窗口的内容。

false

答案 8 :(得分:0)

使用Nilton Vasques解决方案可以是这样:

with(autoComplete) {
    setAdapter(this@YourFragment.adapter)
    setText(itemText)
    showDropDown()
    listSelection = if (itemIndex > 0) itemIndex - 1 else 0 // Because AutoCompleteTextView shows the next row.
    performCompletion()
}

请注意,它将显示一个下拉列表,否则listSelection将不起作用。如果您呼叫dismissDropDown(),则不会选择该项目。如果您不想显示下拉列表,可以使用setOnTouchListener捕获打开列表,但这几乎无济于事(您应该解决过滤问题)。

setOnTouchListener { _, event ->
    if (event.action == MotionEvent.ACTION_DOWN) {
        showDropDown()
        listSelection = if (itemIndex > 0) itemIndex - 1 else 0
        performCompletion()
        requestFocus()
    }
    false
}