切换语言后Exposed下拉菜单自动重新展开问题求助
Exposed下拉菜单切换语言后自动展开的解决方案
问题现象
切换应用语言后,Exposed下拉菜单会自动重新展开,已尝试移除焦点、在生命周期方法中手动关闭菜单,但问题仍未解决。
相关代码
布局XML
<com.google.android.material.textfield.TextInputLayout android:id="@+id/language_menu" style="@style/ExposedDropdownMenuStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="@dimen/sixteen_dp_margin" android:hint="@string/language"> <AutoCompleteTextView android:id="@+id/language_menu_auto_complete" android:layout_width="match_parent" android:layout_height="wrap_content" android:dropDownSelector="@drawable/language_dropdown_bg" android:inputType="none" android:paddingStart="24dp" android:paddingTop="@dimen/sixteen_dp_margin" android:paddingBottom="@dimen/sixteen_dp_margin" /> </com.google.android.material.textfield.TextInputLayout>
Fragment填充菜单(onResume方法)
val languages = resources.getStringArray(R.array.app_languages) val adapter = ArrayAdapter(requireContext(), R.layout.language_list_item, languages) binding.languageMenuAutoComplete.setAdapter(adapter)
语言选择监听器
binding.languageMenuAutoComplete.setOnItemClickListener { _, _, position, _ -> // position 0 = english, 1 = ukrainian, 2 = russian val localeList = when (position) { 1 -> LocaleListCompat.forLanguageTags("uk") 2 -> LocaleListCompat.forLanguageTags("ru") else -> LocaleListCompat.forLanguageTags("en") } AppCompatDelegate.setApplicationLocales(localeList) }
已尝试无效操作
- 移除控件焦点
- 在onResume、onDestroy、onCreate等生命周期方法中调用关闭下拉菜单
可行解决方案
1. 禁用控件状态自动保存
语言切换后,系统会自动恢复View的保存状态,其中包含下拉菜单的展开状态。给AutoCompleteTextView添加android:saveEnabled="false",阻止系统恢复该状态:
<AutoCompleteTextView android:id="@+id/language_menu_auto_complete" ... android:saveEnabled="false" />
2. 延迟关闭下拉菜单
视图状态恢复逻辑可能在onResume之后执行,直接在onResume中关闭菜单会被覆盖。用postDelayed延迟执行关闭操作,确保在状态恢复后生效:
override fun onResume() { super.onResume() val languages = resources.getStringArray(R.array.app_languages) val adapter = ArrayAdapter(requireContext(), R.layout.language_list_item, languages) binding.languageMenuAutoComplete.setAdapter(adapter) binding.languageMenuAutoComplete.postDelayed({ if (binding.languageMenuAutoComplete.isPopupShowing) { binding.languageMenuAutoComplete.dismissDropDown() } }, 100) }
3. 在视图状态恢复后处理
重写Fragment的onViewStateRestored方法,这个方法是系统恢复完视图状态后调用的,在这里关闭菜单能精准拦截自动展开:
override fun onViewStateRestored(savedInstanceState: Bundle?) { super.onViewStateRestored(savedInstanceState) binding.languageMenuAutoComplete.dismissDropDown() }
4. 恢复选中项时避免触发展开
保存用户上次选中的语言位置,重建后直接设置选中文本,同时把setText的第二个参数设为false,避免触发下拉展开:
// 保存选中位置到SharedPreferences private fun saveSelectedLangPos(position: Int) { requireContext().getSharedPreferences("app_settings", Context.MODE_PRIVATE) .edit() .putInt("selected_lang", position) .apply() } // 获取保存的选中位置 private fun getSelectedLangPos(): Int { return requireContext().getSharedPreferences("app_settings", Context.MODE_PRIVATE) .getInt("selected_lang", 0) } // 在选择监听器中保存位置 binding.languageMenuAutoComplete.setOnItemClickListener { _, _, position, _ -> saveSelectedLangPos(position) // 语言切换逻辑... } // 在onResume中设置选中项 override fun onResume() { super.onResume() val languages = resources.getStringArray(R.array.app_languages) val adapter = ArrayAdapter(requireContext(), R.layout.language_list_item, languages) binding.languageMenuAutoComplete.setAdapter(adapter) val selectedPos = getSelectedLangPos() binding.languageMenuAutoComplete.setText(languages[selectedPos], false) }
内容的提问来源于stack exchange,提问作者SonOfaSleep
相关产品推荐
相关产品推荐

