Fix stupid layout, make the details screen scrollable and look better
This commit is contained in:
parent
5bf418db58
commit
5610e46a3f
2 changed files with 144 additions and 92 deletions
|
|
@ -1,23 +1,21 @@
|
|||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.ButtonColors
|
||||
import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
|
|
@ -26,13 +24,7 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.CornerRadius
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.geometry.Size
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
|
|
@ -58,9 +50,9 @@ data class DetailScreen(
|
|||
|
||||
LaunchedEffect(Unit) {
|
||||
pokemonData = withContext(Dispatchers.IO) {
|
||||
fetchPokemonDetails();
|
||||
fetchPokemonDetails()
|
||||
}
|
||||
dataLoaded = true;
|
||||
dataLoaded = true
|
||||
}
|
||||
|
||||
if (!dataLoaded) {
|
||||
|
|
@ -69,12 +61,6 @@ data class DetailScreen(
|
|||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text("Fetching Data from API...")
|
||||
}
|
||||
} else {
|
||||
Box(
|
||||
modifier = Modifier.background(color = Color.White).fillMaxSize(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
//Back Button
|
||||
Button(
|
||||
onClick = { navigator.popAll(); navigator.push(HomeScreen()) },
|
||||
|
|
@ -85,86 +71,90 @@ data class DetailScreen(
|
|||
) {
|
||||
Text("Home")
|
||||
}
|
||||
//Details
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Top,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
KamelImage(
|
||||
resource = asyncPainterResource(pokemon.imageUrl),
|
||||
modifier = Modifier.size(256.dp),
|
||||
contentDescription = "",
|
||||
alignment = Alignment.Center
|
||||
)
|
||||
}
|
||||
//Details
|
||||
Box(
|
||||
modifier = Modifier.size(256.dp).padding(5.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Canvas(modifier = Modifier.matchParentSize()) {
|
||||
drawRoundRect(
|
||||
color = Color.White,
|
||||
topLeft = Offset(0f, 0f),
|
||||
size = Size(size.width, size.height),
|
||||
cornerRadius = CornerRadius(20f, 20f),
|
||||
}
|
||||
} else {
|
||||
Column(
|
||||
modifier = Modifier.background(color = Color.White).fillMaxSize().padding(16.dp)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
verticalArrangement = Arrangement.Top,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Box(modifier = Modifier.align(Alignment.Start)) {
|
||||
//Back Button
|
||||
Button(
|
||||
onClick = { navigator.popAll(); navigator.push(HomeScreen()) },
|
||||
modifier = Modifier.align(Alignment.TopStart),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
backgroundColor = orange, contentColor = Color.White
|
||||
)
|
||||
drawRoundRect(
|
||||
color = Color.Black,
|
||||
topLeft = Offset(0f, 0f),
|
||||
size = Size(size.width, size.height),
|
||||
cornerRadius = CornerRadius(20f, 20f),
|
||||
style = Stroke(1.dp.toPx())
|
||||
)
|
||||
}
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier.padding(16.dp)
|
||||
) {
|
||||
Text(
|
||||
"Name: ${pokemonData?.name}",
|
||||
fontFamily = FontFamily.Monospace,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Text(
|
||||
"Type: ${pokemonData?.type}",
|
||||
fontFamily = FontFamily.Monospace,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Text(
|
||||
"Base XP: ${pokemonData?.baseExperience}",
|
||||
fontFamily = FontFamily.Monospace,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Text(
|
||||
"Height: ${pokemonData?.height}",
|
||||
fontFamily = FontFamily.Monospace,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Text(
|
||||
"Weight: ${pokemonData?.weight}kg",
|
||||
fontFamily = FontFamily.Monospace,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Text("Home")
|
||||
}
|
||||
}
|
||||
//Stats + Progress Bars
|
||||
Box(
|
||||
modifier = Modifier.size(512.dp).padding(5.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
|
||||
// Image
|
||||
KamelImage(
|
||||
resource = asyncPainterResource(pokemon.imageUrl),
|
||||
modifier = Modifier.size(256.dp),
|
||||
contentDescription = "",
|
||||
alignment = Alignment.Center
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
// Details card
|
||||
Card(
|
||||
modifier = Modifier.background(color = Color.White).fillMaxWidth()
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
detailRow("Name:", pokemonData?.name ?: "")
|
||||
detailRow("Type:", pokemonData?.type?.capitalize() ?: "")
|
||||
detailRow("Base XP:", pokemonData?.baseExperience.toString())
|
||||
detailRow("Height:", pokemonData?.height.toString())
|
||||
detailRow("Weight:", pokemonData?.weight.toString())
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
// Stat card
|
||||
PokemonStatCard(
|
||||
hp = pokemonData?.hp ?: 0,
|
||||
attack = pokemonData?.attack ?: 0,
|
||||
defense = pokemonData?.defense ?: 0,
|
||||
specialAttack = pokemonData?.specialAttack ?: 0,
|
||||
specialDefense = pokemonData?.specialDefense ?: 0,
|
||||
speed = pokemonData?.speed ?: 0
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Leave suspend
|
||||
suspend fun fetchPokemonDetails(): PokemonData {
|
||||
private suspend fun fetchPokemonDetails(): PokemonData {
|
||||
val apiString = "https://pokeapi.co/api/v2/pokemon/${pokemon.name.lowercase()}"
|
||||
val json = JSONObject(URL(apiString).readText())
|
||||
return PokemonData.fromJson(json)
|
||||
return PokemonData.fromJson(json)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun detailRow(statName: String, value: String) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically, modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(
|
||||
text = statName,
|
||||
modifier = Modifier.weight(1f),
|
||||
style = MaterialTheme.typography.body1 // Adjust text style as needed
|
||||
)
|
||||
Text(
|
||||
text = value,
|
||||
modifier = Modifier.weight(1f),
|
||||
style = MaterialTheme.typography.body1 // Adjust text style as needed
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
62
composeApp/src/commonMain/kotlin/PokemonStatCard.kt
Normal file
62
composeApp/src/commonMain/kotlin/PokemonStatCard.kt
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.LinearProgressIndicator
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun PokemonStatCard(
|
||||
hp: Int,
|
||||
attack: Int,
|
||||
defense: Int,
|
||||
specialAttack: Int,
|
||||
specialDefense: Int,
|
||||
speed: Int
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(color = Color.White, shape = RoundedCornerShape(8.dp))
|
||||
.padding(16.dp),
|
||||
verticalArrangement = Arrangement.Bottom,
|
||||
) {
|
||||
StatRow("HP", hp, Color.Green)
|
||||
StatRow("Attack", attack, Color.Red)
|
||||
StatRow("Defense", defense, Color.Gray)
|
||||
StatRow("Special Attack", specialAttack, Color.Yellow)
|
||||
StatRow("Special Defense", specialDefense, Color.LightGray)
|
||||
StatRow("Speed", speed, Color.Cyan)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun StatRow(statName: String, progress: Int, color: Color) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(
|
||||
text = "$statName: $progress",
|
||||
modifier = Modifier.weight(1f),
|
||||
style = MaterialTheme.typography.body1
|
||||
)
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
LinearProgressIndicator(
|
||||
progress = progress / 200f,
|
||||
modifier = Modifier.weight(2f),
|
||||
color = color,
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue