You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin通过SharedPreferences存储Spinner列表到RecyclerView仅获取最后选中项问题

问题根因

每次Spinner选中回调触发时,你都重新创建了一个空的ArrayList<Model>,仅将当前选中的单个条目放入列表后,直接覆盖写入SharedPreferences的对应key,之前存储的所有历史选中项都会被清空,因此最终只能读取到最后一次选中的条目。

修复实现

核心逻辑调整:写入新选中项前,先读取SharedPreferences中已经存储的历史列表,将新条目追加到列表后,再把完整的更新后列表写回存储。

修正后的Spinner选中监听代码

spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
    override fun onItemSelected(p0: AdapterView<*>?, p1: View?, position: Int, id: Long) {
        val gson = Gson()
        val listType = object : TypeToken<ArrayList<Model>>() {}.type
        
        // 1. 读取已存储的历史选中列表,无历史数据时初始化空列表
        val savedJson = sharedPreferences.getString("list", null)
        val dataList: ArrayList<Model> = if (!savedJson.isNullOrEmpty()) {
            gson.fromJson(savedJson, listType)
        } else {
            arrayListOf()
        }

        // 2. 追加当前选中的条目,可按需开启去重逻辑
        val currentSelected = Model(department[position])
        // 若Model是data class,equals方法会自动生成,去重判断可正常生效
        if (currentSelected !in dataList) {
            dataList.add(currentSelected)
        }

        // 3. 将更新后的完整列表重新写入SharedPreferences
        val updatedJson = gson.toJson(dataList)
        sharedPreferences.edit()
            .putString("list", updatedJson)
            .apply()

        // 可选:选中后立刻刷新RecyclerView展示,无需等待页面重载
        (binding.recyclerView.adapter as? AddEditTextAdapter)?.apply {
            notifyDataSetChanged()
        }
    }

    override fun onNothingSelected(parent: AdapterView<*>?) {
        // 无选中项时无需处理
    }
}

优化后的列表加载逻辑

private fun initRecyclerView() {
    val gson = Gson()
    val listType = object : TypeToken<ArrayList<Model>>() {}.type
    val savedJson = sharedPreferences.getString("list", null)
    val dataList: ArrayList<Model> = if (!savedJson.isNullOrEmpty()) {
        gson.fromJson(savedJson, listType)
    } else {
        arrayListOf()
    }

    binding.recyclerView.layoutManager = LinearLayoutManager(this)
    binding.recyclerView.adapter = AddEditTextAdapter(dataList)
}
注意事项
  • 若你的Model类不是Kotlin data class,需要手动重写equals()和hashCode()方法,否则列表去重判断无法正常工作
  • Spinner的onItemSelected会在控件首次加载时自动触发一次回调,若不需要初始化时自动添加默认选中项,可添加一个布尔标记位区分用户手动触发和初始化自动触发的场景
  • 若需要支持删除已选中的条目,删除操作后同样要把更新后的列表重新序列化写入SharedPreferences,保证存储数据和展示数据一致

内容的提问来源于stack exchange,提问作者Khushbu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 11:54:14