Android Material下拉菜单重访Fragment时选项不加载问题求助
问题排查与解决方案
核心问题
重访Fragment重建Material外露式下拉菜单时,仅显示上次选中的选项,其余seconds/minutes/hours/days选项消失,首次加载正常。
关键代码差异与修复方向
对比首次创建和重建的代码,存在几个可能的问题点,逐一修复:
1. 统一ArrayAdapter的上下文
首次创建时使用requireContext()初始化ArrayAdapter,重建时误用了timerLayout.context(即ContextThemeWrapper实例),这可能导致Adapter的视图绑定异常,下拉选项无法渲染。
修复代码:
将重建代码中的:
val arrayAdapter = ArrayAdapter(timerLayout.context, R.layout.dropdown_menu_item, timeUnits)
改为:
val arrayAdapter = ArrayAdapter(requireContext(), R.layout.dropdown_menu_item, timeUnits)
2. 验证选中单位的索引合法性
重建时通过list.size - 1获取选中单位的索引,若list的长度与time_units数组长度不匹配,会导致设置错误的文本,进而引发菜单异常。
添加索引校验:
val timeUnitsList = ArrayList(listOf(*resources.getStringArray(R.array.time_units))) val selectedIndex = list.size - 1 // 确保索引在合法范围内 if (selectedIndex in timeUnitsList.indices) { timeUnitsMenu.setText(timeUnitsList[selectedIndex], false) } else { // fallback到默认值,比如minutes timeUnitsMenu.setText(getString(R.string.minutes), false) }
3. 检查restoreTimerFields方法的副作用
如果restoreTimerFields方法中存在修改timeUnitsMenu的Adapter、过滤下拉数据或清空选项的逻辑,会直接导致下拉选项丢失。需确保该方法仅负责恢复计时器的输入字段,不改动下拉菜单的配置。
4. 强制刷新菜单状态
设置选中文本后,强制通知Adapter刷新数据,确保下拉选项正常显示:
timeUnitsMenu.setText(timeUnitsList[selectedIndex], false) arrayAdapter.notifyDataSetChanged()
完整修复后的重建代码片段
for (i in 0 until stepsList.size) { if (stepsList[i] is MutableList<*>) { val list = stepsList[i] as MutableList<*> val ctx = ContextThemeWrapper(activity, R.style.timeUnitsMenu) val timerLayout = LayoutInflater.from(ctx).inflate(R.layout.timer, null) timerLayout.findViewById<ImageButton>(R.id.delete_timer).setOnClickListener { timerView -> deleteStep(timerView) } val timerContainer = timerLayout.findViewById<LinearLayout>(R.id.timer_settings_container) val timeUnitsMenu = timerLayout.findViewById<AutoCompleteTextView>(R.id.time_units_menu) val timeUnits = resources.getStringArray(R.array.time_units) // 统一使用requireContext()创建Adapter val arrayAdapter = ArrayAdapter(requireContext(), R.layout.dropdown_menu_item, timeUnits) println("${arrayAdapter.getItem(0)} ${arrayAdapter.getItem(1)} ${arrayAdapter.getItem(2)} ${arrayAdapter.getItem(3)}") timeUnitsMenu.setAdapter(arrayAdapter) timeUnitsMenu.addTextChangedListener { restoreTimerFields(timerContainer, i) } val timeUnitsList = ArrayList(listOf(*resources.getStringArray(R.array.time_units))) val selectedIndex = list.size - 1 // 校验索引并设置文本 if (selectedIndex in timeUnitsList.indices) { timeUnitsMenu.setText(timeUnitsList[selectedIndex], false) } else { timeUnitsMenu.setText(getString(R.string.minutes), false) } // 强制刷新Adapter arrayAdapter.notifyDataSetChanged() stepsContainer.addView(timerLayout, i) } }
内容的提问来源于stack exchange,提问作者Connor Smith
相关产品推荐
相关产品推荐

