From 6f68590ff45b89432ba349dfeb77927b1aff03d5 Mon Sep 17 00:00:00 2001 From: Guillerius5 Date: Thu, 23 Oct 2025 13:51:05 +0200 Subject: [PATCH] trabajo terminado --- .../es/fpsumma/dam2/intro/MainActivity.kt | 3 +- .../dam2/intro/ui/components/NameField.kt | 38 ++++++++++++++ .../dam2/intro/ui/screens/CounterScreen.kt | 24 ++++++--- .../dam2/intro/ui/screens/InputDemoScreen.kt | 49 ++++++++++++------- .../es/fpsumma/dam2/intro/ui/theme/Color.kt | 6 ++- .../es/fpsumma/dam2/intro/ui/theme/Theme.kt | 17 ++++--- app/src/main/res/values/strings.xml | 1 + 7 files changed, 104 insertions(+), 34 deletions(-) create mode 100644 app/src/main/java/es/fpsumma/dam2/intro/ui/components/NameField.kt diff --git a/app/src/main/java/es/fpsumma/dam2/intro/MainActivity.kt b/app/src/main/java/es/fpsumma/dam2/intro/MainActivity.kt index 0462544..99b346c 100644 --- a/app/src/main/java/es/fpsumma/dam2/intro/MainActivity.kt +++ b/app/src/main/java/es/fpsumma/dam2/intro/MainActivity.kt @@ -9,6 +9,7 @@ import androidx.compose.material3.Surface import androidx.compose.ui.Modifier import com.ivancorrales.basicjetpackcompose.ui.theme.IntroTheme import es.fpsumma.dam2.intro.ui.screens.CounterScreen +import es.fpsumma.dam2.intro.ui.screens.InputDemoScreen class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { @@ -19,7 +20,7 @@ class MainActivity : ComponentActivity() { modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { - CounterScreen() + InputDemoScreen() } } } diff --git a/app/src/main/java/es/fpsumma/dam2/intro/ui/components/NameField.kt b/app/src/main/java/es/fpsumma/dam2/intro/ui/components/NameField.kt new file mode 100644 index 0000000..3a16ac9 --- /dev/null +++ b/app/src/main/java/es/fpsumma/dam2/intro/ui/components/NameField.kt @@ -0,0 +1,38 @@ +package es.fpsumma.dam2.intro.ui.components + +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.input.ImeAction + +@Composable +fun NameField( + value: String, + onValueChange: (String) -> Unit, + error: String?, // Estado del error a mostrar + onDone: () -> Unit, // Callback para el evento de teclado (tecla 'Done') + modifier: Modifier = Modifier +) { + OutlinedTextField( + value = value, + onValueChange = onValueChange, + label = { Text("Tu nombre") }, // Usar stringResource() + isError = error != null, + supportingText = { + if (error != null) { + // Muestra el mensaje de error con el color de error + Text(error!!, color = MaterialTheme.colorScheme.error) + } + }, + singleLine = true, + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), + // Ejecuta el callback onDone cuando se presiona la acción de teclado 'Done' + keyboardActions = KeyboardActions(onDone = { onDone() }), + modifier = modifier.fillMaxWidth() + ) +} \ No newline at end of file diff --git a/app/src/main/java/es/fpsumma/dam2/intro/ui/screens/CounterScreen.kt b/app/src/main/java/es/fpsumma/dam2/intro/ui/screens/CounterScreen.kt index 404c688..020f3ac 100644 --- a/app/src/main/java/es/fpsumma/dam2/intro/ui/screens/CounterScreen.kt +++ b/app/src/main/java/es/fpsumma/dam2/intro/ui/screens/CounterScreen.kt @@ -6,18 +6,22 @@ import androidx.compose.material.icons.outlined.Refresh import androidx.compose.material3.* import androidx.compose.runtime.* +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import es.fpsumma.dam2.intro.R @Composable fun CounterScreen() { - var count by remember { mutableStateOf(0) } - + var count by rememberSaveable { mutableStateOf(5) } + val sizeBoton= (count*8).dp Column( modifier = Modifier .fillMaxSize() @@ -25,26 +29,33 @@ fun CounterScreen() { horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(16.dp) ) { - Text("Hola mi amig@!", style = MaterialTheme.typography.headlineMedium) + Text(text=stringResource(id= R.string.Good_Morning), style = MaterialTheme.typography.headlineMedium) Text("Contador: $count", style = MaterialTheme.typography.titleLarge) Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) { Button( - onClick = {}, + onClick = {count++}, + modifier = Modifier.semantics { contentDescription = "Incrementar" } ) { Text("+1") } FilledTonalButton( - onClick = {}, + onClick = {if(count > 0 )count--}, modifier = Modifier.semantics { contentDescription = "Decrementar" } ) { Text("-1") } IconButton( - onClick = {}, + onClick = {count=0}, modifier = Modifier.size(48.dp) ) { Icon(Icons.Outlined.Refresh, contentDescription = "Reiniciar contador") } } + Button( + onClick = {}, + enabled = false, + modifier=Modifier.width(sizeBoton) + + ){} } } @@ -53,3 +64,4 @@ fun CounterScreen() { private fun CounterPreview() { CounterScreen() } + diff --git a/app/src/main/java/es/fpsumma/dam2/intro/ui/screens/InputDemoScreen.kt b/app/src/main/java/es/fpsumma/dam2/intro/ui/screens/InputDemoScreen.kt index c11ccc9..c798cc9 100644 --- a/app/src/main/java/es/fpsumma/dam2/intro/ui/screens/InputDemoScreen.kt +++ b/app/src/main/java/es/fpsumma/dam2/intro/ui/screens/InputDemoScreen.kt @@ -11,6 +11,7 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import es.fpsumma.dam2.intro.ui.components.NameField @Composable fun InputDemoScreen() { @@ -19,43 +20,57 @@ fun InputDemoScreen() { var name by rememberSaveable { mutableStateOf("") } var greeting by remember { mutableStateOf(null) } - // Calcula el error en función del texto (sin estado extra) Pista -> derivedStateOf - // TODO: valida name: no vacío, mínimo 3 caracteres (trim). + val nameToGreet = name.trim() + + // Lógica de validación (Puntos 2 y 3 implementados) val error: String? by remember(name) { derivedStateOf { - null + if (name.isEmpty()) { + "El nombre no puede estar vacío" + } else if (nameToGreet.length < 3) { + "Mínimo 3 caracteres" + } else { + null + } } } + val isButtonEnabled = error == null + fun submit() { - if (error == null) { - greeting = "Hola, 👋" + if (isButtonEnabled) { + greeting = "Hola, $nameToGreet 👋" focusManager.clearFocus() } } Column(Modifier.fillMaxSize().padding(24.dp)) { - OutlinedTextField( + + // ------------------------------------------------------------------ + + NameField( value = name, - onValueChange = { name = it }, - label = { Text("Tu nombre") }, - isError = error != null, - supportingText = { if (error != null) Text(error!!) }, - singleLine = true, - keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), - keyboardActions = KeyboardActions(onDone = { submit() }), - modifier = Modifier.fillMaxWidth() + onValueChange = { + name = it // Recibe el nuevo valor y actualiza el estado + greeting = null // Reinicia el saludo + }, + error = error, // Pasa el estado del error + onDone = ::submit // Pasa la referencia a la función submit ) + // ------------------------------------------------------------------ + Spacer(Modifier.height(16.dp)) Button( onClick = { submit() }, + enabled = isButtonEnabled, modifier = Modifier.fillMaxWidth() ) { - Text("Saludar") + Text("Saludar") // Usar stringResource() } Spacer(Modifier.height(16.dp)) - if (error == null && name.isNotBlank()) { - Text(greeting?: "" ) + + if (greeting != null) { + Text(greeting!!, style = MaterialTheme.typography.headlineSmall) } } } diff --git a/app/src/main/java/es/fpsumma/dam2/intro/ui/theme/Color.kt b/app/src/main/java/es/fpsumma/dam2/intro/ui/theme/Color.kt index c45da49..ac86b48 100644 --- a/app/src/main/java/es/fpsumma/dam2/intro/ui/theme/Color.kt +++ b/app/src/main/java/es/fpsumma/dam2/intro/ui/theme/Color.kt @@ -1,4 +1,4 @@ -package com.ivancorrales.basicjetpackcompose.ui.theme +package es.fpsumma.dam2.intro.ui.theme import androidx.compose.ui.graphics.Color @@ -8,4 +8,6 @@ val Pink80 = Color(0xFFEFB8C8) val Purple40 = Color(0xFF6650a4) val PurpleGrey40 = Color(0xFF625b71) -val Pink40 = Color(0xFF7D5260) \ No newline at end of file +val Pink40 = Color(0xFF7D5260) + +val Green= Color(0xFF1B5E20) \ No newline at end of file diff --git a/app/src/main/java/es/fpsumma/dam2/intro/ui/theme/Theme.kt b/app/src/main/java/es/fpsumma/dam2/intro/ui/theme/Theme.kt index cb6c5d5..010e095 100644 --- a/app/src/main/java/es/fpsumma/dam2/intro/ui/theme/Theme.kt +++ b/app/src/main/java/es/fpsumma/dam2/intro/ui/theme/Theme.kt @@ -1,21 +1,22 @@ package com.ivancorrales.basicjetpackcompose.ui.theme -import android.app.Activity import android.os.Build -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.material3.ColorScheme import androidx.compose.material3.MaterialTheme import androidx.compose.material3.darkColorScheme import androidx.compose.material3.dynamicDarkColorScheme import androidx.compose.material3.dynamicLightColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable -import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext -import com.ivancorrales.basicjetpackcompose.ui.theme.LightColorScheme +import es.fpsumma.dam2.intro.ui.theme.Green +import es.fpsumma.dam2.intro.ui.theme.Pink40 +import es.fpsumma.dam2.intro.ui.theme.Pink80 +import es.fpsumma.dam2.intro.ui.theme.Purple40 +import es.fpsumma.dam2.intro.ui.theme.PurpleGrey40 +import es.fpsumma.dam2.intro.ui.theme.PurpleGrey80 private val DarkColorScheme = darkColorScheme( - primary = Purple80, + primary = Green, secondary = PurpleGrey80, tertiary = Pink80 ) @@ -28,8 +29,8 @@ private val LightColorScheme = lightColorScheme( @Composable fun IntroTheme( - darkTheme: Boolean = false, - dynamicColor: Boolean = true, + darkTheme: Boolean = true, + dynamicColor: Boolean = false, content: @Composable () -> Unit ) { val colorScheme = when { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 656572b..065ef48 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,4 @@ Intro + Buenos dias \ No newline at end of file