Browse Source

feat: enhance history expanded view to match drawer details

- Updated expanded view to show all Pokemon data fields like the drawer
- Added comprehensive data sections: Pokemon Info, Types, Base Stats, Properties, Origin, Ability & Moves, Additional
- Implemented multi-column layouts: two-column, three-column, checkbox rows, and mixed rows
- Added visual elements: checkboxes (☑/☐), section headers, proper spacing
- Improved data presentation with consistent formatting and organization
- Enhanced layout helper methods for complex data display

Data sections now include:
- Pokemon Info: Species, Dex #, Nickname, Gender, Level, Nature
- Types: Primary/Secondary types, Tera type
- Base Stats: HP, ATK, DEF, SP.ATK, SP.DEF, SPEED (when available)
- Properties: Shiny , Alpha 🅰, Favorited , Pokeball type
- Origin: Game source, Language, Original Trainer info
- Ability & Moves: Pokemon ability and move list (up to 4)
- Additional: Stamps, Labels, Marks (when present)

The expanded view now provides the same comprehensive information as the ResultsBottomDrawer for consistent user experience.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
feature/pgh-1-results-display-history
Quildra 5 months ago
parent
commit
bc715fbc25
  1. 328
      app/src/main/java/com/quillstudios/pokegoalshelper/ui/HistoryAdapter.kt

328
app/src/main/java/com/quillstudios/pokegoalshelper/ui/HistoryAdapter.kt

@ -304,31 +304,111 @@ class HistoryAdapter(
private fun addPokemonInfoViews(pokemonInfo: com.quillstudios.pokegoalshelper.PokemonInfo, context: Context)
{
// Basic info section
addSectionHeader("Basic Info", context)
pokemonInfo.level?.let { addInfoRow("Level", it.toString(), context) }
pokemonInfo.gender?.let { addInfoRow("Gender", it, context) }
pokemonInfo.nature?.let { addInfoRow("Nature", it, context) }
// Types section
if (pokemonInfo.primaryType != null || pokemonInfo.secondaryType != null) {
addSectionHeader("Types", context)
val typeText = when {
pokemonInfo.primaryType != null && pokemonInfo.secondaryType != null ->
"${pokemonInfo.primaryType} / ${pokemonInfo.secondaryType}"
pokemonInfo.primaryType != null -> pokemonInfo.primaryType
else -> "Unknown"
// Basic Pokemon Info Section
addSectionHeader("Pokemon Info", context)
addTwoColumnRow(
leftLabel = "Species", leftValue = pokemonInfo.species ?: "Unknown",
rightLabel = "Dex #", rightValue = pokemonInfo.nationalDexNumber?.let { "#$it" } ?: "N/A",
context = context
)
addTwoColumnRow(
leftLabel = "Nickname", leftValue = pokemonInfo.nickname ?: "None",
rightLabel = "Gender", rightValue = pokemonInfo.gender ?: "Unknown",
context = context
)
addTwoColumnRow(
leftLabel = "Level", leftValue = pokemonInfo.level?.toString() ?: "N/A",
rightLabel = "Nature", rightValue = pokemonInfo.nature ?: "Unknown",
context = context
)
// Types Section
addSectionHeader("Types", context)
val typeDisplay = when {
pokemonInfo.primaryType != null && pokemonInfo.secondaryType != null ->
"${pokemonInfo.primaryType} / ${pokemonInfo.secondaryType}"
pokemonInfo.primaryType != null -> pokemonInfo.primaryType
else -> "Unknown"
}
addTwoColumnRow(
leftLabel = "Type", leftValue = typeDisplay,
rightLabel = "Tera", rightValue = pokemonInfo.teraType ?: "N/A",
context = context
)
// Stats Section (if available)
pokemonInfo.stats?.let { stats ->
addSectionHeader("Base Stats", context)
addThreeColumnRow(
leftLabel = "HP", leftValue = stats.hp?.toString() ?: "?",
middleLabel = "ATK", middleValue = stats.attack?.toString() ?: "?",
rightLabel = "DEF", rightValue = stats.defense?.toString() ?: "?",
context = context
)
addThreeColumnRow(
leftLabel = "SP.ATK", leftValue = stats.spAttack?.toString() ?: "?",
middleLabel = "SP.DEF", middleValue = stats.spDefense?.toString() ?: "?",
rightLabel = "SPEED", rightValue = stats.speed?.toString() ?: "?",
context = context
)
}
// Special Properties Section
addSectionHeader("Properties", context)
addCheckboxRow(
leftLabel = "Shiny", leftChecked = pokemonInfo.isShiny,
rightLabel = "Alpha", rightChecked = pokemonInfo.isAlpha,
context = context
)
addMixedRow(
leftLabel = "Favorited", leftChecked = pokemonInfo.isFavorited,
rightLabel = "Pokeball", rightValue = pokemonInfo.pokeballType ?: "Unknown",
context = context
)
// Game Origin Section
addSectionHeader("Origin", context)
addTwoColumnRow(
leftLabel = "Game", leftValue = pokemonInfo.gameSource ?: "Unknown",
rightLabel = "Language", rightValue = pokemonInfo.language ?: "Unknown",
context = context
)
pokemonInfo.originalTrainerName?.let { trainerName ->
addTwoColumnRow(
leftLabel = "OT Name", leftValue = trainerName,
rightLabel = "OT ID", rightValue = pokemonInfo.originalTrainerId ?: "Unknown",
context = context
)
}
// Ability & Moves
pokemonInfo.ability?.let { ability ->
addSectionHeader("Ability & Moves", context)
addInfoRow("Ability", ability, context)
}
if (pokemonInfo.moves.isNotEmpty()) {
if (pokemonInfo.ability == null) {
addSectionHeader("Moves", context)
}
addInfoRow("Type", typeText, context)
pokemonInfo.teraType?.let { addInfoRow("Tera Type", it, context) }
addInfoRow("Moves", pokemonInfo.moves.take(4).joinToString(", "), context)
}
// Special properties
if (pokemonInfo.isShiny || pokemonInfo.isAlpha || pokemonInfo.isFavorited) {
addSectionHeader("Properties", context)
if (pokemonInfo.isShiny) addInfoRow("Shiny", "✨ Yes", context)
if (pokemonInfo.isAlpha) addInfoRow("Alpha", "🅰 Yes", context)
if (pokemonInfo.isFavorited) addInfoRow("Favorited", "⭐ Yes", context)
// Additional Data
if (pokemonInfo.stamps.isNotEmpty() || pokemonInfo.labels.isNotEmpty() || pokemonInfo.marks.isNotEmpty()) {
addSectionHeader("Additional", context)
if (pokemonInfo.stamps.isNotEmpty()) {
addInfoRow("Stamps", pokemonInfo.stamps.joinToString(", "), context)
}
if (pokemonInfo.labels.isNotEmpty()) {
addInfoRow("Labels", pokemonInfo.labels.joinToString(", "), context)
}
if (pokemonInfo.marks.isNotEmpty()) {
addInfoRow("Marks", pokemonInfo.marks.joinToString(", "), context)
}
}
}
@ -392,6 +472,210 @@ class HistoryAdapter(
expandedContainer.addView(row)
}
private fun addTwoColumnRow(
leftLabel: String, leftValue: String,
rightLabel: String, rightValue: String,
context: Context
)
{
val row = LinearLayout(context).apply {
orientation = LinearLayout.HORIZONTAL
setPadding(0, dpToPx(context, 2), 0, dpToPx(context, 2))
}
// Left column
val leftColumn = createColumnItem(leftLabel, leftValue, context)
leftColumn.layoutParams = LinearLayout.LayoutParams(
0,
ViewGroup.LayoutParams.WRAP_CONTENT,
1f
)
// Right column
val rightColumn = createColumnItem(rightLabel, rightValue, context)
rightColumn.layoutParams = LinearLayout.LayoutParams(
0,
ViewGroup.LayoutParams.WRAP_CONTENT,
1f
).apply {
setMargins(dpToPx(context, 8), 0, 0, 0)
}
row.addView(leftColumn)
row.addView(rightColumn)
expandedContainer.addView(row)
}
private fun addThreeColumnRow(
leftLabel: String, leftValue: String,
middleLabel: String, middleValue: String,
rightLabel: String, rightValue: String,
context: Context
)
{
val row = LinearLayout(context).apply {
orientation = LinearLayout.HORIZONTAL
setPadding(0, dpToPx(context, 2), 0, dpToPx(context, 2))
}
// Left column
val leftColumn = createColumnItem(leftLabel, leftValue, context)
leftColumn.layoutParams = LinearLayout.LayoutParams(
0,
ViewGroup.LayoutParams.WRAP_CONTENT,
1f
)
// Middle column
val middleColumn = createColumnItem(middleLabel, middleValue, context)
middleColumn.layoutParams = LinearLayout.LayoutParams(
0,
ViewGroup.LayoutParams.WRAP_CONTENT,
1f
).apply {
setMargins(dpToPx(context, 4), 0, dpToPx(context, 4), 0)
}
// Right column
val rightColumn = createColumnItem(rightLabel, rightValue, context)
rightColumn.layoutParams = LinearLayout.LayoutParams(
0,
ViewGroup.LayoutParams.WRAP_CONTENT,
1f
)
row.addView(leftColumn)
row.addView(middleColumn)
row.addView(rightColumn)
expandedContainer.addView(row)
}
private fun createColumnItem(label: String, value: String, context: Context): LinearLayout
{
return LinearLayout(context).apply {
orientation = LinearLayout.VERTICAL
gravity = android.view.Gravity.START
val labelView = TextView(context).apply {
text = "$label:"
setTextSize(TypedValue.COMPLEX_UNIT_SP, 9f)
setTextColor(ContextCompat.getColor(context, android.R.color.darker_gray))
}
val valueView = TextView(context).apply {
text = value
setTextSize(TypedValue.COMPLEX_UNIT_SP, 11f)
setTextColor(ContextCompat.getColor(context, android.R.color.white))
typeface = android.graphics.Typeface.DEFAULT_BOLD
}
addView(labelView)
addView(valueView)
}
}
private fun addCheckboxRow(
leftLabel: String, leftChecked: Boolean,
rightLabel: String, rightChecked: Boolean,
context: Context
)
{
val row = LinearLayout(context).apply {
orientation = LinearLayout.HORIZONTAL
setPadding(0, dpToPx(context, 2), 0, dpToPx(context, 2))
}
// Left checkbox
val leftCheckbox = createCheckboxItem(leftLabel, leftChecked, context)
leftCheckbox.layoutParams = LinearLayout.LayoutParams(
0,
ViewGroup.LayoutParams.WRAP_CONTENT,
1f
)
// Right checkbox
val rightCheckbox = createCheckboxItem(rightLabel, rightChecked, context)
rightCheckbox.layoutParams = LinearLayout.LayoutParams(
0,
ViewGroup.LayoutParams.WRAP_CONTENT,
1f
).apply {
setMargins(dpToPx(context, 8), 0, 0, 0)
}
row.addView(leftCheckbox)
row.addView(rightCheckbox)
expandedContainer.addView(row)
}
private fun addMixedRow(
leftLabel: String, leftChecked: Boolean,
rightLabel: String, rightValue: String,
context: Context
)
{
val row = LinearLayout(context).apply {
orientation = LinearLayout.HORIZONTAL
setPadding(0, dpToPx(context, 2), 0, dpToPx(context, 2))
}
// Left checkbox
val leftCheckbox = createCheckboxItem(leftLabel, leftChecked, context)
leftCheckbox.layoutParams = LinearLayout.LayoutParams(
0,
ViewGroup.LayoutParams.WRAP_CONTENT,
1f
)
// Right text item
val rightItem = createColumnItem(rightLabel, rightValue, context)
rightItem.layoutParams = LinearLayout.LayoutParams(
0,
ViewGroup.LayoutParams.WRAP_CONTENT,
1f
).apply {
setMargins(dpToPx(context, 8), 0, 0, 0)
}
row.addView(leftCheckbox)
row.addView(rightItem)
expandedContainer.addView(row)
}
private fun createCheckboxItem(label: String, checked: Boolean, context: Context): LinearLayout
{
return LinearLayout(context).apply {
orientation = LinearLayout.HORIZONTAL
gravity = android.view.Gravity.CENTER_VERTICAL
// Checkbox symbol
val checkboxView = TextView(context).apply {
text = if (checked) "" else ""
setTextSize(TypedValue.COMPLEX_UNIT_SP, 14f)
setTextColor(
if (checked) ContextCompat.getColor(context, android.R.color.holo_green_light)
else ContextCompat.getColor(context, android.R.color.darker_gray)
)
layoutParams = LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
).apply {
setMargins(0, 0, dpToPx(context, 6), 0)
}
}
// Label
val labelView = TextView(context).apply {
text = label
setTextSize(TypedValue.COMPLEX_UNIT_SP, 11f)
setTextColor(ContextCompat.getColor(context, android.R.color.white))
}
addView(checkboxView)
addView(labelView)
}
}
private fun addDeleteButton(result: DetectionResult, position: Int, context: Context)
{
val deleteButton = Button(context).apply {

Loading…
Cancel
Save