RecyclerView仅显示单个条目求助:如何展示全部历史数据
问题原因分析
- 仅在有新数据传入时加载历史数据:当前代码只有当Intent携带
Score和CompScore参数时才调用readLogData(),直接从主页面进入排行榜不会加载历史数据。 - 日期解析不匹配:写入文件用自定义格式
dd-MMMM-yyyy,但读取时用LocalDate.parse()默认格式,导致历史数据日期解析失败,无法添加到列表。 - 历史数据读取逻辑错误:文件中每两行对应一条完整记录(用户分数+电脑分数),但当前按单行处理,把单条记录拆成两个条目,且电脑分数被错误设为0。
- 重复反转列表:读取数据后反转一次,添加新数据后又反转一次,导致列表顺序混乱。
修复方案
- 无论是否有新数据,进入页面都读取历史数据。
- 使用一致的日期格式化器处理写入和读取。
- 按成对行读取文件内容,组装完整的
LeaderBoardItem。 - 用明确的排序逻辑替代重复反转,保持列表按日期降序排列。
- 读取历史数据前清空列表,避免重复添加。
修改后的完整代码
package com.example.pigdicegame import android.content.Intent import android.os.Bundle import android.view.View import android.widget.Button import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import java.io.* import java.time.LocalDate import java.time.LocalDateTime import java.time.format.DateTimeFormatter import java.util.* const val LeaderBoard_File = "LeaderBoard.txt" class leaderboard : AppCompatActivity() { private lateinit var btnSwitchBack: Button private lateinit var recyclerView: RecyclerView private var leaderList = ArrayList<LeaderBoardItem>() private lateinit var LeaderBoardadapter: LeaderBoardadapter // 统一使用的日期格式化器,保证读写格式一致 private val dateFormatter = DateTimeFormatter.ofPattern("dd-MMMM-yyyy", Locale.getDefault()) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_leaderboard) btnSwitchBack = findViewById(R.id.btnSwitchBack) recyclerView = findViewById(R.id.leaderboardRecycler) LeaderBoardadapter = LeaderBoardadapter(leaderList) recyclerView.layoutManager = LinearLayoutManager(applicationContext) recyclerView.itemAnimator = DefaultItemAnimator() recyclerView.adapter = LeaderBoardadapter // 优先加载历史数据,无论是否有新数据传入 readLogData() try { val extras = intent.extras if (extras != null && extras.containsKey("Score") && extras.containsKey("CompScore")) { val score: Int = extras.getInt("Score", 0) val compScore: Int = extras.getInt("CompScore", 0) val formattedDate = LocalDateTime.now().format(dateFormatter) val date = LocalDate.now() // 追加数据到文件,使用use自动关闭流 val file = File(filesDir, LeaderBoard_File) try { FileWriter(file, true).use { fileWriter -> BufferedWriter(fileWriter).use { bufferedWriter -> bufferedWriter.write("You : $score $formattedDate\n") bufferedWriter.write("Computer : $compScore $formattedDate\n") } } // 添加新条目并重新排序 leaderList.add(LeaderBoardItem(score, compScore, date)) leaderList.sortByDescending { it.date } LeaderBoardadapter.notifyDataSetChanged() } catch (e: IOException) { e.printStackTrace() } } } catch (e: Exception) { e.printStackTrace() } } private fun readLogData() { try { val file = File(filesDir, LeaderBoard_File) if (file.exists()) { leaderList.clear() // 清空旧数据,避免重复加载 val lines = file.readLines().filter { it.isNotBlank() } // 过滤空行 // 每两行解析为一条完整记录(用户行+电脑行) for (i in lines.indices step 2) { if (i + 1 < lines.size) { val userLine = lines[i] val compLine = lines[i + 1] // 解析用户分数和日期 val userParts = userLine.split(":").takeIf { it.size >= 2 } ?: continue val userScoreDate = userParts[1].trim().split(" ").takeIf { it.size >= 2 } ?: continue val userScore = userScoreDate[0].toIntOrNull() ?: continue val date = LocalDate.parse(userScoreDate[1], dateFormatter) // 解析电脑分数 val compParts = compLine.split(":").takeIf { it.size >= 2 } ?: continue val compScore = compParts[1].trim().split(" ")[0].toIntOrNull() ?: 0 leaderList.add(LeaderBoardItem(userScore, compScore, date)) } } // 按日期降序排序,最新记录在最前 leaderList.sortByDescending { it.date } LeaderBoardadapter.notifyDataSetChanged() } } catch (e: Exception) { e.printStackTrace() } } fun btnSwitchBackOnClick(v: View) { val intent = Intent(this, MainActivity::class.java) btnSwitchBack.isEnabled = false startActivity(intent) } }
内容的提问来源于stack exchange,提问作者nightowl989
相关产品推荐
相关产品推荐

