Fix stupid layout, make the details screen scrollable and look better

This commit is contained in:
FirephoenixX02 2024-04-12 13:08:05 +02:00
parent 5bf418db58
commit 5610e46a3f
2 changed files with 144 additions and 92 deletions

View file

@ -1,23 +1,21 @@
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size 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.Button
import androidx.compose.material.ButtonColors
import androidx.compose.material.ButtonDefaults 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.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.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@ -26,13 +24,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier 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.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 androidx.compose.ui.unit.dp
import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
@ -58,9 +50,9 @@ data class DetailScreen(
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
pokemonData = withContext(Dispatchers.IO) { pokemonData = withContext(Dispatchers.IO) {
fetchPokemonDetails(); fetchPokemonDetails()
} }
dataLoaded = true; dataLoaded = true
} }
if (!dataLoaded) { if (!dataLoaded) {
@ -69,12 +61,6 @@ data class DetailScreen(
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
Text("Fetching Data from API...") Text("Fetching Data from API...")
}
} else {
Box(
modifier = Modifier.background(color = Color.White).fillMaxSize(),
contentAlignment = Alignment.Center
) {
//Back Button //Back Button
Button( Button(
onClick = { navigator.popAll(); navigator.push(HomeScreen()) }, onClick = { navigator.popAll(); navigator.push(HomeScreen()) },
@ -85,86 +71,90 @@ data class DetailScreen(
) { ) {
Text("Home") Text("Home")
} }
//Details }
Column( } else {
modifier = Modifier.fillMaxSize(), Column(
verticalArrangement = Arrangement.Top, modifier = Modifier.background(color = Color.White).fillMaxSize().padding(16.dp)
horizontalAlignment = Alignment.CenterHorizontally .verticalScroll(rememberScrollState()),
) { verticalArrangement = Arrangement.Top,
KamelImage( horizontalAlignment = Alignment.CenterHorizontally
resource = asyncPainterResource(pokemon.imageUrl), ) {
modifier = Modifier.size(256.dp), Box(modifier = Modifier.align(Alignment.Start)) {
contentDescription = "", //Back Button
alignment = Alignment.Center Button(
) onClick = { navigator.popAll(); navigator.push(HomeScreen()) },
} modifier = Modifier.align(Alignment.TopStart),
//Details colors = ButtonDefaults.buttonColors(
Box( backgroundColor = orange, contentColor = Color.White
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),
) )
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( Text("Home")
"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
)
} }
} }
//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 private suspend fun fetchPokemonDetails(): PokemonData {
suspend fun fetchPokemonDetails(): PokemonData {
val apiString = "https://pokeapi.co/api/v2/pokemon/${pokemon.name.lowercase()}" val apiString = "https://pokeapi.co/api/v2/pokemon/${pokemon.name.lowercase()}"
val json = JSONObject(URL(apiString).readText()) 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
)
} }
} }

View 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,
)
}
}