Android Studio(Kotlin)中AutoCompleteTextView下拉项仅短暂显示问题
问题解决:AutoCompleteTextView下拉列表闪显后消失
问题场景
在基于Kotlin的Android Studio项目中实现搜索栏,需求是展示列表中包含输入内容的项,并按内容在字符串中的索引排序。当前输入内容位于字符串开头时功能完全正常,但当输入内容处于字符串中间位置时,匹配的下拉项会闪显后立即消失。
现有代码
XML布局
<AutoCompleteTextView android:id="@+id/editTextSearch" android:layout_width="372dp" android:layout_height="44dp" android:autofillHints="Email" android:background="@drawable/edittext" android:hint="@string/search_username" android:layout_marginTop="30dp" android:inputType="text" android:paddingStart="10dp" android:paddingEnd="10dp" android:dropDownHeight="wrap_content" android:completionThreshold="1" android:imeOptions="actionSearch" app:layout_constraintTop_toBottomOf="@+id/txtHome" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" />
Kotlin逻辑
FirebaseHelper.getAllUsernames { usernames -> // Set adapter binding.editTextSearch.setAdapter( ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, usernames) ) // Add text change listener binding.editTextSearch.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { // Convert input to string val query = s.toString().trim() // Filter usernames containing the query val filtered = usernames.filter { username -> username.contains(query, ignoreCase = true) } //sort by index val sorted = filtered.sortedBy { username -> username.indexOf(query, ignoreCase = true) } // Update adapter with filtered (or sorted) list binding.editTextSearch.setAdapter( ArrayAdapter(this@MainActivity, android.R.layout.simple_dropdown_item_1line, sorted) ) binding.editTextSearch.showDropDown() } override fun afterTextChanged(s: Editable?) {} }) }
问题原因
每次文本变化时都重新创建并设置新的ArrayAdapter,这会导致AutoCompleteTextView的下拉列表状态被强制重置。当匹配项不是字符串前缀时,系统默认的自动补全逻辑会触发下拉关闭,此时调用showDropDown()就会出现闪显后消失的冲突现象,重复设置适配器还会破坏UI组件的原有状态,引发不稳定。
解决方案
复用同一个ArrayAdapter,通过更新适配器内部的数据来刷新列表,而非每次新建适配器。这样能保持AutoCompleteTextView的状态一致性,彻底解决下拉列表闪烁问题。
修改后的Kotlin代码
FirebaseHelper.getAllUsernames { usernames -> // 初始化适配器并保存引用,避免重复创建 val adapter = ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, usernames) binding.editTextSearch.setAdapter(adapter) binding.editTextSearch.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { val query = s.toString().trim() val filtered = usernames.filter { username -> username.contains(query, ignoreCase = true) } val sorted = filtered.sortedBy { username -> username.indexOf(query, ignoreCase = true) } // 复用现有适配器,更新数据而非重建 adapter.clear() adapter.addAll(sorted) adapter.notifyDataSetChanged() // 根据结果控制下拉列表显示/隐藏 if (sorted.isNotEmpty()) { binding.editTextSearch.showDropDown() } else { binding.editTextSearch.dismissDropDown() } } override fun afterTextChanged(s: Editable?) {} }) }
额外优化点
- 空结果处理:当过滤后无匹配项时主动关闭下拉列表,避免无效显示
- 性能优化:可添加查询内容缓存,仅当查询内容真正变化时才执行过滤排序操作(可选)
内容的提问来源于stack exchange,提问作者Sammay
相关产品推荐
相关产品推荐

