androidkotlinandroid-jetpack-compose

I have an error in Kotlin caused by a mutableState


The error is produced when I called the element, it seems that the first argument is of a different type than expected, but I don't understand why, I'm confused, by the way I'm learning jetpack-compose

My code

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            QuizAppTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    val puntuacion by remember {
                        mutableStateOf(0)
                    }
                    QuizElement(puntuacion, vidas = 3)
                }
            }
        }
    }
}
@Composable
fun QuizElement(puntuacion: MutableState<Int>, vidas: Int) {
    // Una variable local para guardar la opción seleccionada por el usuario
    var opcion by remember { mutableStateOf("") }
    // Una variable local para guardar la respuesta correcta
    val respuesta = "A"
    // Una variable local para obtener el contexto de la actividad
    val context = LocalContext.current
    Column {
        // Un texto que muestra la pregunta
        Text(text = "¿Cuál es la capital de Colombia?")
        // Un row que contiene dos botones con las opciones A y B
        Row {
            Button(onClick = { opcion = "A" }) {
                Text(text = "A) Bogotá")
            }
            Button(onClick = { opcion = "B" }) {
                Text(text = "B) Medellín")
            }
        }
        // Un row que contiene dos botones con las opciones C y D
        Row {
            Button(onClick = { opcion = "C" }) {
                Text(text = "C) Cali")
            }
            Button(onClick = { opcion = "D" }) {
                Text(text = "D) Cartagena")
            }
        }
        // Un botón que envía la respuesta y actualiza la puntuación si es correcta
        Button(onClick = {
            if (opcion == respuesta) {
                // Incrementar la puntuación en uno
                puntuacion.value++
                // Mostrar un mensaje de felicitación
                Toast.makeText(context, "¡Respuesta correcta!", Toast.LENGTH_SHORT).show()
            } else {
                // Mostrar un mensaje de error
                Toast.makeText(context, "Respuesta incorrecta", Toast.LENGTH_SHORT).show()
            }
        }) {
            Text(text = "Enviar")
        }
        // Un texto que muestra la puntuación actual
        Text(text = "Puntuación: ${puntuacion.value}")
    }
}

i have no idea about this error 'Type mismatch: inferred type is Int but MutableState was expected' i tried to update Kotlin but not work


Solution

  • You're creating a delegated mutable state of an Integer in this line of code:

    val puntuacion by remember { mutableStateOf(0) }
    

    So the result is a puntuacion of a Integer type, not MutableState<Int>, that's because the by is a delegate, what does a delegate mean? It is a shortcut that saves you from calling puntuacion.value every time, so you just use by instead of = so you can use the Integer directly. Let me give you another example:

    val string1 by remember { mutableStateOf("somerandomstring") } <--- this is a string
    
    val string2 = remember { mutableStateOf("somerandomstring") } <--- this is a mutable state of a string
    
    //When you want to get string1's value
    println(string1) <--- you can use it directly
    
    //When you want to get string2's value, you need to use .value
    println(string2.value) <--- this is without using 'by' delegate
    

    You should always check your variable's type when you create them. You can check the type of your variable by hovering with your mouse cursor over the variable's name. QuizElement is expecting a mutable state of an Integer, but you're passing an Integer, that's why the Kotlin compiler got confused.

    NOTE: It is better to use the new mutableIntStateOf(yourintegerhere) instead of mutableStateOf(yourintegerhere) when you are creating mutable states of integers, that's because they're better for memory and faster.

    There are also mutableFloatStateOf, mutableDoubleStateOf...etc

    NOTE 2: Your QuizElement should receive an Integer directly in its parameter, don't pass mutable states around, you should pass their values instead, otherwise you'll run into Non-recomposition problems quite often (where changing values wouldn't trigger recomposition), unless you know what you're doing.