Nat Strangerweather
02/25/2022, 4:12 PMvar enabled by remember { mutableStateOf(true) }
and var visible by remember { mutableStateOf(true) }
. When I reload the Composable with new data, these variables do not return to their original true
value. Why is that? And how can I make sure they are updated too?Kirill Grouchnikov
02/25/2022, 4:14 PMremember
then?Nat Strangerweather
02/25/2022, 4:19 PMval color by animateColorAsState(
if (visible) tileColor else Color.White,
animationSpec = tween(durationMillis = 1000)
)
Kirill Grouchnikov
02/25/2022, 4:21 PMvar
or mutableStateOf
Nat Strangerweather
02/25/2022, 4:25 PMKirill Grouchnikov
02/25/2022, 4:30 PMremember
is for maintaining the value over multiple re-entrances into your composableNat Strangerweather
02/25/2022, 4:31 PMvar
, my color does not change.Kirill Grouchnikov
02/25/2022, 4:33 PMif
statement) can't track those changes, so you do need the mutableStateOf
wrapperAdam Powell
02/25/2022, 5:20 PMNat Strangerweather
02/25/2022, 5:25 PM@OptIn(ExperimentalFoundationApi::class)
@Composable
fun GameBoard(boardLetters: Array<Letter>) {
Column(
horizontalAlignment = Alignment.Start,
verticalArrangement = Arrangement.Center,
) {
LazyVerticalGrid(
cells = GridCells.Fixed(7),
verticalArrangement = <http://Arrangement.Top|Arrangement.Top>
) {
items(boardLetters) { data ->
Piece(data)
}
}
}
}
@Composable
fun Piece(data: Letter) {
val viewModel: MainViewModel = viewModel()
var enabled by remember { mutableStateOf(true) }
var tileColor by remember { mutableStateOf(Color.White) }
var visible by remember { mutableStateOf(true) }
val scope = rememberCoroutineScope()
val bestScore by viewModel.bestScore.observeAsState()
val context = LocalContext.current
val view = LocalView.current
when (data.value) {
1 -> tileColor = Color(0xff7189BF)
2 -> tileColor = Color(0xffBF8B67)
3 -> tileColor = Color(0xffFFAD60)
4 -> tileColor = Color(0xffDF7599)
5 -> tileColor = Color(0xffA275E3)
8 -> tileColor = Color(0xff72D6C9)
10 -> tileColor = Color(0xff655D8A)
}
val color by animateColorAsState(
if (visible) tileColor else Color.White,
animationSpec = tween(durationMillis = 1000)
)
val superscript = SpanStyle(
baselineShift = BaselineShift.Superscript,
fontSize = 12.sp,
color = Color.White
)
Box(
modifier = Modifier
.fillMaxSize()
.aspectRatio(1f)
.padding(2.dp)
.shadow(7.dp, shape = RoundedCornerShape(8.dp))
.clip(shape = RoundedCornerShape(8.dp))
.background(color)
.clickable(enabled = enabled) {
view.playSoundEffect(SoundEffectConstants.CLICK)
viewModel.deleteResultString()
for (v in data.name) {
viewModel.onNewLetterValue(data.value)
enabled = false
}
viewModel.onNewLetter(data.name)
scope.launch {
DataStoreUtils.saveBestScore(context, "bestScoreKey", bestScore!!)
}
visible = !visible
},
contentAlignment = Alignment.Center
) {
Text(
text = buildAnnotatedString {
append(data.name)
withStyle(superscript) {
append(" ${data.value}")
}
}, style = TextStyle(Color.White, fontSize = 20.sp),
fontWeight = FontWeight.ExtraBold
)
}
}
Adam Powell
02/25/2022, 5:41 PMPiece
composable is trying to own and control too much. Whenever you encounter a situation where you feel like you want to "reset" a composable, that's a sign that you should hoist the state you want to be able to reset out of `remember`s inside the composable itself, probably into a class.Letter
and enabled
, tileColor
and visible
properties, that same class can either have a reset
method, or possibly even better, you can generate a new collection of instances of your class to pass to the Piece
composables, and the act of generating that new board is all the reset you need.Nat Strangerweather
02/25/2022, 5:46 PMPiece
Composable had a lot going on it it!Adam Powell
02/25/2022, 5:50 PM@Composable
fun MyComposable() {
var one by remember { mutableStateOf(initialOne) }
var two by remember { mutableStateOf(initialTwo) }
into
class MyComposableState(
one: OneType,
two: TwoType
) {
var one by mutableStateOf(one)
var two by mutableStateOf(two)
}
@Composable
fun MyComposable(
state: MyComposableState = remember { MyComposableState(initialOne, initialTwo) }
) {