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

Kotlin如何实现跨页面SharedPreferences存储IBAN数据并列表展示

IBAN存储应用两个核心问题修复方案

一、修复AddIbanActivity保存数据覆盖历史的问题

  • 根因:页面启动时直接初始化了空的ibanList,没有提前读取SharedPreferences中已经存储的历史IBAN数据,每次保存都是把仅包含当前新录入条目的列表写入,直接覆盖旧数据。
  • 修复逻辑:页面初始化时,先从SharedPreferences读取已存的IBAN列表JSON,反序列化为ArrayList<IbanModel>赋值给ibanList,没有历史数据时再使用空列表。

修改后的AddIbanActivity完整代码如下:

package com.example.ibansfer

import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.ibansfer.databinding.ActivityAddIbanBinding
import com.example.ibansfer.models.IbanModel
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken


class AddIbanActivity : AppCompatActivity() {
    private lateinit var binding: ActivityAddIbanBinding
    private var ibanList: ArrayList<IbanModel> = ArrayList()
    private val gson = Gson()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityAddIbanBinding.inflate(layoutInflater)
        setContentView(binding.root)

        setTitle("IBAN bilgisi ekle")
        supportActionBar?.setDisplayHomeAsUpEnabled(true)

        val sharedPreferences = getSharedPreferences("ibans", MODE_PRIVATE)
        // 初始化时先读取历史存储的列表
        val savedJson = sharedPreferences.getString("ibans", null)
        if (!savedJson.isNullOrEmpty()) {
            val type = object : TypeToken<ArrayList<IbanModel>>() {}.type
            ibanList = gson.fromJson(savedJson, type)
        }

        binding.ibanSaveBttn.setOnClickListener {
            val ibanOwner = binding.ibanOwner.text.toString().trim()
            val bankName = binding.bankName.text.toString().trim()
            val ibanAdress = binding.ibanAdress.text.toString().trim()

            if (ibanOwner.isEmpty() || bankName.isEmpty() || ibanAdress.isEmpty()) {
                Toast.makeText(this, "Lütfen tüm alanları doldurunuz.", Toast.LENGTH_LONG).show()
            } else {
                ibanList.add(IbanModel(ibanOwner, bankName, ibanAdress))
                // 保存最新列表
                val editor = sharedPreferences.edit()
                val newJson = gson.toJson(ibanList)
                editor.putString("ibans", newJson)
                editor.apply()

                Toast.makeText(this, "IBAN bilgileri başarıyla eklendi.", Toast.LENGTH_LONG).show()
                finish()
            }
        }
    }

    override fun onSupportNavigateUp(): Boolean {
        finish()
        return true
    }
}

上述代码额外补充了左上角返回按钮的逻辑,同时对输入内容做了首尾空格过滤,避免用户输入全空格的无效内容。

二、首页读取IBAN列表并渲染展示

  • 实现逻辑:
    • 首页使用RecyclerView作为列表容器,编写对应Adapter绑定IBAN条目数据
    • 在onResume生命周期中读取SharedPreferences里的最新IBAN列表——从AddIbanActivity返回首页时会触发onResume,可以保证每次看到的都是最新数据
    • 把读取到的列表提交给Adapter,刷新列表展示

步骤1:编写列表条目布局

在layout目录下新建item_iban.xml作为单个IBAN条目的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="16dp"
    android:layout_margin="8dp"
    android:background="@android:color/white"
    android:elevation="2dp">

    <TextView
        android:id="@+id/tvIbanOwner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        android:textStyle="bold"/>

    <TextView
        android:id="@+id/tvBankName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:textSize="14sp"/>

    <TextView
        android:id="@+id/tvIbanAddress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:textSize="14sp"
        android:textColor="@android:color/darker_gray"/>

</LinearLayout>

步骤2:编写RecyclerView适配器

新建IbanListAdapter.kt处理列表数据和视图的绑定:

package com.example.ibansfer

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.ibansfer.databinding.ItemIbanBinding
import com.example.ibansfer.models.IbanModel

class IbanListAdapter(private val ibanList: List<IbanModel>) : RecyclerView.Adapter<IbanListAdapter.IbanViewHolder>() {

    inner class IbanViewHolder(val binding: ItemIbanBinding) : RecyclerView.ViewHolder(binding.root)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): IbanViewHolder {
        val binding = ItemIbanBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return IbanViewHolder(binding)
    }

    override fun onBindViewHolder(holder: IbanViewHolder, position: Int) {
        val currentItem = ibanList[position]
        holder.binding.tvIbanOwner.text = currentItem.ibanOwner
        holder.binding.tvBankName.text = currentItem.bankName
        holder.binding.tvIbanAddress.text = currentItem.ibanAdress
    }

    override fun getItemCount(): Int {
        return ibanList.size
    }
}

步骤3:编写首页逻辑

首先修改首页布局activity_main.xml,添加跳转按钮和列表容器:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btnAddIban"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Yeni IBAN ekle"
        android:layout_margin="16dp"/>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rvIbanList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

在首页Activity(默认是MainActivity)中编写数据读取和列表初始化逻辑:

package com.example.ibansfer

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.ibansfer.databinding.ActivityMainBinding
import com.example.ibansfer.models.IbanModel
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private val gson = Gson()
    private lateinit var ibanAdapter: IbanListAdapter
    private var ibanList: ArrayList<IbanModel> = ArrayList()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 初始化RecyclerView
        ibanAdapter = IbanListAdapter(ibanList)
        binding.rvIbanList.apply {
            layoutManager = LinearLayoutManager(this@MainActivity)
            adapter = ibanAdapter
        }

        // 跳转到添加IBAN页面
        binding.btnAddIban.setOnClickListener {
            startActivity(Intent(this, AddIbanActivity::class.java))
        }
    }

    override fun onResume() {
        super.onResume()
        // 每次页面回到前台时读取最新的IBAN列表
        val sharedPreferences = getSharedPreferences("ibans", MODE_PRIVATE)
        val savedJson = sharedPreferences.getString("ibans", null)
        ibanList.clear()
        if (!savedJson.isNullOrEmpty()) {
            val type = object : TypeToken<ArrayList<IbanModel>>() {}.type
            val savedList: ArrayList<IbanModel> = gson.fromJson(savedJson, type)
            ibanList.addAll(savedList)
        }
        // 通知适配器刷新列表
        ibanAdapter.notifyDataSetChanged()
    }
}

注意:保证IbanModel的字段名和录入属性一一对应,同时确认模块级build.gradle中已经引入Gson和RecyclerView的依赖,否则代码会编译失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 15:54:17