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..bb99f6b 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,17 +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.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) } + //rememberSaveable hace que al rotar la pantalla no cabmie el valor + var count by rememberSaveable { mutableStateOf(5) } + val botonTamaño = (count * 5).dp Column( modifier = Modifier @@ -25,26 +30,36 @@ fun CounterScreen() { horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(16.dp) ) { - Text("Hola mi amig@!", style = MaterialTheme.typography.headlineMedium) + Text(stringResource (R.string.buenos_dias), 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(botonTamaño) + + ) + { } } } 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..7b21428 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() { @@ -18,38 +19,54 @@ fun InputDemoScreen() { var name by rememberSaveable { mutableStateOf("") } var greeting by remember { mutableStateOf(null) } - + val trimmedName = name.trim() // 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 error: String? by remember(name) { derivedStateOf { - null + + if (name.isEmpty()){ + "el nombre no puede estar vacio!!" + + } else if (trimmedName.length <3){ + + "El nombre tiene que tener mas de 3 caracteres!" + }else{ + null + } } } + //Si error es null: Esto significa + // que NO HAY un mensaje de error + // (porque la validación fue exitosa). + // Por lo tanto, la expresión error == null es true. + val isInputValid = error == null fun submit() { if (error == null) { - greeting = "Hola, 👋" + greeting = "Hola, " +trimmedName+ "👋" 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 = isInputValid, modifier = Modifier.fillMaxWidth() + + ) { Text("Saludar") } 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..453ba3b 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 @@ -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(0xFF037A03) \ 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..c0f2e9a 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 @@ -15,9 +15,10 @@ import androidx.compose.ui.platform.LocalContext import com.ivancorrales.basicjetpackcompose.ui.theme.LightColorScheme private val DarkColorScheme = darkColorScheme( - primary = Purple80, + primary = Green, secondary = PurpleGrey80, tertiary = Pink80 + ) private val LightColorScheme = lightColorScheme( @@ -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..97a98e2 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