使用SimpleDateFormat与SharedPreferences保存日期后页面返回日期异常
问题原因与修复方案
核心问题
- onStart强制覆盖日期:每次页面回到前台触发
onStart时,你都会把data1的文本重置为当前系统时间,直接覆盖了loadData加载的已保存日期。 - 选中日期未持久化:用户选择完日期后,没有调用
saveData把选中值存入SharedPreferences,导致返回页面时加载不到之前的选择。 - 冗余代码干扰:
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
相关产品推荐
相关产品推荐

