Рекомпозиция не происходит, несмотря на изменение переменной mutableStateOf

Я хочу, чтобы кнопки случайно меняли цвет при нажатии. С этой целью я ввожу фиктивную изменяемую переменную состояния flag, которая изменяется при событии щелчка. Однако после этого никакой рекомпозиции не происходит:

@Composable
fun Cell(modifier: Modifier){
    val color = listOf(Color.Red, Color.Blue, Color.Black).shuffled()[0]
    var flag by remember { mutableStateOf(false) }
    val bc = ButtonColors(color, Color.White, Color.White, Color.White)
    Button(onClick = {flag=true}, modifier=modifier, colors = bc,
        shape = RoundedCornerShape(8.dp) ) {}
}

@OptIn(ExperimentalLayoutApi::class)
@Composable
fun FlowTable(name: String, modifier: Modifier = Modifier) {
    val rows = 3
    val columns = 3
    FlowRow(
        modifier = Modifier.padding(4.dp),
        horizontalArrangement = Arrangement.spacedBy(4.dp),
        maxItemsInEachRow = rows
    ) {
        val itemModifier = Modifier
            .padding(4.dp)
            .height(80.dp)
            .weight(1f)
            .clip(RoundedCornerShape(8.dp))
            .background(Color.Blue)
        repeat(rows * columns) {
            Cell(modifier)
        }
    }

}

Однако, по мнению отладчика, происходит событие onClick, и сразу после него программа выполняет строку var flag by remember { mutableStateOf(false) }, но дальше не продолжает (и не выполняет предыдущие строки)!

каковы ваши ожидания?

sasikumar 27.08.2024 06:10

на основе вашего кода. вы не понимаете, как работает состояние в Jetpack Compose, вам следует прочитать это здесь Developer.android.com/develop/ui/compose/state

Renz Salanga 27.08.2024 06:16
1
2
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что переменная состояния flag обновляется, но она нигде не используется в вашей компоновке Cell. При компоновке переменная состояния должна быть прочитана где-то в компонуемом объекте, чтобы при ее изменении произошла рекомпозиция.

Чтобы кнопка меняла цвет при нажатии, создайте переменную состояния randomColor. Эта переменная хранит случайный цвет, а затем обновляет эту переменную новым случайным цветом при нажатии кнопки.

Вот как вы можете изменить свой код:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            MyApplicationTheme {
                Box(
                    modifier = Modifier.fillMaxSize(),
                    contentAlignment = Alignment.Center
                ) {
                    FlowTable(name = "table name")
                }
            }
        }
    }
}


@Composable
fun Cell(modifier: Modifier){
    val colors = listOf(Color.Red, Color.Blue, Color.Black)

    var randomColor by remember {
        mutableStateOf(colors.random())
    }

    Button(
        onClick= { randomColor = colors.random() },
        modifier=modifier.background(color = randomColor),
        shape = RoundedCornerShape(8.dp),
        colors = ButtonDefaults.buttonColors().copy(containerColor = randomColor)
    ) {}
}

@OptIn(ExperimentalLayoutApi::class)
@Composable
fun FlowTable(name: String, modifier: Modifier = Modifier) {
    val rows = 3
    val columns = 3
    FlowRow(
        modifier = modifier.padding(4.dp),
        horizontalArrangement = Arrangement.spacedBy(4.dp),
        maxItemsInEachRow = rows
    ) {
        repeat(rows * columns) {
            Cell(
                modifier = Modifier
                    .padding(4.dp)
                    .height(80.dp)
                    .weight(1f)
                    .clip(RoundedCornerShape(8.dp))
                    .background(Color.Blue)
            )
        }
    }
}

Демо:

Другие вопросы по теме