Android Kotlin:如何从函数向Activity传递字符串数组适配Spinner
问题根因
- 类型定义完全不统一:定义的数据类首字段为
Array<String>类型,工具函数返回时却传入Int类型的数组资源ID,还混用了未定义的数据类名,解构时直接将首变量声明为Int,直接触发类型不匹配编译错误。 - 缺失资源解析逻辑:Android中
R.array.xxx是Int类型的资源索引,不是实际的字符串数组实体,必须通过Context调用对应方法才能拿到可直接使用的Array<String>。 - 分支逻辑不全:工具函数中的
when表达式作为返回值使用时未穷举所有分支,本身就会触发编译错误。
修复方案
按以下步骤修改代码即可完全解决问题:
1. 统一数据类定义
因为工具函数返回的是数组资源ID,直接将数据类首字段改为Int类型的资源ID,统一类名,删除不必要的方法重写(Int是值类型,data类自动实现的equals/hashCode即可满足需求):
data class SelectingDistrictLocationArray( val districtListResId: Int, val districtVisibility: Int, val stateWarningVisibility: Int, val recyclerViewVisibility: Int )
2. 修正工具类逻辑
统一返回值类名、补全when分支,避免编译错误:
object RegionSelectionFunctions { fun selectedState(state: String): SelectingDistrictLocationArray { return when (state) { "-- Select State --" -> SelectingDistrictLocationArray( districtListResId = R.array.empty, districtVisibility = View.GONE, stateWarningVisibility = View.VISIBLE, recyclerViewVisibility = View.GONE ) // 此处补充其他州对应的数组资源分支即可 else -> SelectingDistrictLocationArray( districtListResId = R.array.empty, districtVisibility = View.GONE, stateWarningVisibility = View.VISIBLE, recyclerViewVisibility = View.GONE ) } } }
3. 修正Activity侧逻辑
拿到资源ID后先解析为实际字符串数组,再传入ArrayAdapter,补全缺失的控件赋值逻辑:
fun selectingDistrictLocation() { val (districtListResId, districtVisibility, stateWarningVisibility, recyclerViewVisibility) = RegionSelectionFunctions.selectedState(SelectedStateName) district_location.visibility = districtVisibility state_warning.visibility = stateWarningVisibility // 补上之前遗漏的列表可见性赋值 districts_recycler_view.visibility = recyclerViewVisibility // 核心修复:将资源ID解析为实际的字符串数组 val districtArray = resources.getStringArray(districtListResId) val locationDistrictAdapter = ArrayAdapter( this, R.layout.support_simple_spinner_dropdown_item, districtArray ) districts_spinner_location.adapter = locationDistrictAdapter districts_spinner_location.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onItemSelected( adapterViewDistrict: AdapterView<*>?, view: View?, position: Int, id: Long ) { DistrictSelectedName = adapterViewDistrict?.getItemAtPosition(position).toString() } override fun onNothingSelected(parent: AdapterView<*>?) {} } }
注意:不推荐在工具类中传入Context直接解析字符串数组返回,容易引发Context内存泄漏,资源解析逻辑放在Activity/Fragment这类View层组件中实现是更规范的做法。
内容的提问来源于stack exchange,提问作者CHETAN
相关产品推荐
相关产品推荐

