Home > OS >  dynamically change text in cards - Jetpack Compose state
dynamically change text in cards - Jetpack Compose state

Time:04-04

New to Compose and struggling hard with more complex state cases.

I cant seem to change the text dynamically in these cards, only set the text manually. Each button press should change the text in a box, starting left to right, leaving the next boxes empty.

What is wrong here?

UI:

val viewModel = HomeViewModel()
val guessArray = viewModel.guessArray


@Composable
fun HomeScreen() {
    Column(
        modifier = Modifier
            .fillMaxWidth()
    ) {
        WordGrid()
        Keyboard()
    }
}


@Composable
fun WordGrid() {
    CardRow()
}


@Composable
fun Keyboard() {
    Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement     = Arrangement.SpaceEvenly) {
    MyKeyboardButton(text = "A", 35)
    MyKeyboardButton(text = "B", 35)
   }
}

@Composable
fun MyCard(text: String) {
    Card(

        modifier = Modifier
        .padding(4.dp, 8.dp)
        .height(55.dp)
        .aspectRatio(1f),
    backgroundColor = Color.White,
    border = BorderStroke(2.dp, Color.Black),
) {
    Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
        Text(
            text = text,
            fontSize = 20.sp,
            )
        }
    }
}

@Composable
fun CardRow() {
    guessArray.forEach { rowCards ->
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            rowCards.forEach {
                MyCard(it)
            println(it)
            }
        }
    }
}

@Composable
fun MyKeyboardButton(text: String, width: Int) {

    Button(
        onClick = {
            guessArray[viewModel.currentRow][viewModel.column] = text
            viewModel.column  = 1
        },
        modifier = Modifier
            .width(width.dp)
            .height(60.dp)
            .padding(0.dp, 2.dp)
    ) {
        Text(text = text, textAlign = TextAlign.Center)
        }
    }

ViewModel:

class HomeViewModel : ViewModel() {

var currentRow = 0
var guessArray = Array(5) { Array(6) { "" }.toMutableList() }
var column = 0
}

The grid is created, but the text is never changed.

CodePudding user response:

To make Compose view recompose with the new value, a mutable state should be used.

You're already using it with remember in your composable, but it also needs to be used in your view model for properties, which should trigger recomposition.

class HomeViewModel : ViewModel() {
    var currentRow  = 0
    val guessArray = List(5) { List(6) { "" }.toMutableStateList() }
    var column = 0
}
  • Related