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

使用SimpleDateFormat与SharedPreferences保存日期后页面返回日期异常

问题原因与修复方案

核心问题

  1. onStart强制覆盖日期:每次页面回到前台触发onStart时,你都会把data1的文本重置为当前系统时间,直接覆盖了loadData加载的已保存日期。
  2. 选中日期未持久化:用户选择完日期后,没有调用saveData把选中值存入SharedPreferences,导致返回页面时加载不到之前的选择。
  3. 冗余代码干扰:loadData里的savedString变量完全无用,属于无效代码。

修复步骤

  • 删掉onStart中设置当前时间的代码,避免覆盖已保存的日期
  • 在日期选择完成的回调里,调用saveData保存选中的日期
  • 清理loadData里的冗余代码
  • 可选优化:初始化日历为已保存的日期,让DatePicker弹窗默认打开上次选中的日期

修正后的完整代码

import android.content.Context
import android.os.Bundle
import android.widget.DatePicker
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import java.text.SimpleDateFormat
import java.util.*

class FT02Activ01 : AppCompatActivity() {
    private lateinit var data1: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_ft02_activ01)
        data1 = findViewById(R.id.data)
        loadData()
    }

    override fun onStart() {
        super.onStart()
        val cal = Calendar.getInstance()
        
        // 初始化日历为已保存的日期(如果存在)
        data1.text?.takeIf { it.isNotEmpty() }?.let { savedDate ->
            runCatching {
                val sdf = SimpleDateFormat("dd/MM/yyyy", Locale.US)
                cal.time = sdf.parse(savedDate)!!
            }
        }

        val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
            cal.set(Calendar.YEAR, year)
            cal.set(Calendar.MONTH, monthOfYear)
            cal.set(Calendar.DAY_OF_MONTH, dayOfMonth)
            val myFormat = "dd/MM/yyyy"
            val sdf = SimpleDateFormat(myFormat, Locale.US)
            val selectedDate = sdf.format(cal.time)
            data1.text = selectedDate
            // 保存选中的日期
            saveData()
        }

        data1.setOnClickListener {
            DatePickerDialog(
                this, dateSetListener,
                cal.get(Calendar.YEAR),
                cal.get(Calendar.MONTH),
                cal.get(Calendar.DAY_OF_MONTH)
            ).show()
        }
    }

    private fun saveData() {
        val sharedPreferences = getSharedPreferences("sharedPrefs", Context.MODE_PRIVATE)
        val editor = sharedPreferences.edit()
        editor.putString("data_KEY", data1.text.toString())
        editor.apply()
    }

    private fun loadData(){
        val sharedPreferences = getSharedPreferences("sharedPrefs", Context.MODE_PRIVATE)
        // 无保存日期时默认显示当前时间
        val savedDate = sharedPreferences.getString("data_KEY", null) ?: run {
            SimpleDateFormat("dd/MM/yyyy", Locale.US).format(System.currentTimeMillis())
        }
        data1.text = savedDate
    }
}

额外优化(可选)

Android官方推荐使用Java 8+的日期API替代过时的SimpleDateFormat和Calendar,避免线程安全问题和API警告(需在build.gradle中启用coreLibraryDesugaring):

// 替换日期处理相关代码
import java.time.LocalDate
import java.time.format.DateTimeFormatter

// 初始化日历
val formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy")
data1.text?.takeIf { it.isNotEmpty() }?.let { savedDate ->
    runCatching {
        val localDate = LocalDate.parse(savedDate, formatter)
        cal.set(localDate.year, localDate.monthValue - 1, localDate.dayOfMonth)
    }
}

// 日期选择回调中
val localDate = LocalDate.of(year, monthOfYear + 1, dayOfMonth)
val selectedDate = formatter.format(localDate)
data1.text = selectedDate
saveData()

// loadData中默认日期
val savedDate = sharedPreferences.getString("data_KEY", null) ?: run {
    formatter.format(LocalDate.now())
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 02:35:32