Android盘点程序API获取数据后Spinner控件不显示选项问题求助
问题根因
- 时序逻辑错误:
getInventories()发起的是异步网络请求,你在请求发起后立刻执行spinAdapt()初始化适配器,此时网络请求还未返回,listInventory是空数组。后续网络请求成功把数据添加到listInventory后,没有通知适配器更新,所以Spinner不会刷新显示新数据。 - 自定义类适配问题:你使用自定义的
ItemOfInventory类作为适配器数据源,系统默认的android.R.layout.simple_spinner_item布局会调用数据源对象的toString()方法获取显示内容,如果ItemOfInventory没有重写toString()方法,会显示类名+内存地址的无效内容,看起来就像没有选项。 - 代码不规范:你声明的
ArrayList没有指定泛型类型,可能存在类型转换异常风险。
修复步骤
1. 重写ItemOfInventory类的toString方法
在你的ItemOfInventory.kt中添加toString实现,返回要在Spinner中展示的文本:
data class ItemOfInventory(val id_Inventory: Int, val inventory_Name: String) { // 重写toString,直接返回物资名称用于Spinner显示 override fun toString(): String { return inventory_Name } }
2. 修正Activity中的逻辑
两种修正方案选一种即可:
方案一:网络请求成功后再初始化适配器
修改AddClassesActivity.kt代码:
package com.example.inventorizationmpt class AddClassesActivity : AppCompatActivity() { lateinit var inventoriesSpinner: Spinner // 明确指定ArrayList泛型为ItemOfInventory lateinit var listInventory : ArrayList<ItemOfInventory> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_add_classes) listInventory = ArrayList() inventoriesSpinner = findViewById(R.id.inventories_spinner) // 只发起请求,不立刻初始化适配器 getInventories() } fun spinAdapt(){ val spinnerAdapter = ArrayAdapter(this@AddClassesActivity, android.R.layout.simple_spinner_item,listInventory) spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) inventoriesSpinner.adapter = spinnerAdapter } fun getInventories(){ val inventorizationService = ServiceBuilder.buildService(InventorizationService::class.java) val requestCall = inventorizationService.getInventoriesList() requestCall.enqueue(object : Callback<List<ItemOfInventory>>{ override fun onResponse( call: Call<List<ItemOfInventory>>, response: Response<List<ItemOfInventory>> ) { if (response.isSuccessful){ val listForSpinner = response.body() ?: return for (item in listForSpinner){ listInventory.add( ItemOfInventory( item.id_Inventory, item.inventory_Name ) ) } // 数据加载完成后再初始化适配器 spinAdapt() }else { Toast.makeText(this@AddClassesActivity, "服务器出错,请稍后重试", Toast.LENGTH_LONG).show() } } override fun onFailure(call: Call<List<ItemOfInventory>>, t: Throwable) { Toast.makeText(this@AddClassesActivity, "网络请求失败,请检查网络连接", Toast.LENGTH_LONG).show() } }) } }
方案二:初始化适配器后,数据更新时通知适配器刷新
package com.example.inventorizationmpt class AddClassesActivity : AppCompatActivity() { lateinit var inventoriesSpinner: Spinner lateinit var listInventory : ArrayList<ItemOfInventory> // 把适配器提升为全局变量 lateinit var spinnerAdapter: ArrayAdapter<ItemOfInventory> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_add_classes) listInventory = ArrayList() inventoriesSpinner = findViewById(R.id.inventories_spinner) // 先初始化适配器 spinAdapt() // 再发起请求 getInventories() } fun spinAdapt(){ spinnerAdapter = ArrayAdapter(this@AddClassesActivity, android.R.layout.simple_spinner_item,listInventory) spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) inventoriesSpinner.adapter = spinnerAdapter } fun getInventories(){ val inventorizationService = ServiceBuilder.buildService(InventorizationService::class.java) val requestCall = inventorizationService.getInventoriesList() requestCall.enqueue(object : Callback<List<ItemOfInventory>>{ override fun onResponse( call: Call<List<ItemOfInventory>>, response: Response<List<ItemOfInventory>> ) { if (response.isSuccessful){ val listForSpinner = response.body() ?: return for (item in listForSpinner){ listInventory.add( ItemOfInventory( item.id_Inventory, item.inventory_Name ) ) } // 通知适配器数据更新 spinnerAdapter.notifyDataSetChanged() }else { Toast.makeText(this@AddClassesActivity, "服务器出错,请稍后重试", Toast.LENGTH_LONG).show() } } override fun onFailure(call: Call<List<ItemOfInventory>>, t: Throwable) { Toast.makeText(this@AddClassesActivity, "网络请求失败,请检查网络连接", Toast.LENGTH_LONG).show() } }) } }
内容的提问来源于stack exchange,提问作者staruhhha
相关产品推荐
相关产品推荐

