I have this composable here with a history, an input/output, and a button to show/hide the history (I have removed the parameters unnecessary to my concern):
@Composable
fun MainWindow(
isShowingHistory: Boolean,
showHistory: () -> Unit,
hideHistory: () -> Unit,
) {
Column(modifier = Modifier.fillMaxSize()) {
History(modifier = Modifier.weight(1f))
Surface(
color = contentColor.copy(0.04f),
modifier = Modifier.fillMaxWidth(),
) {
Column(
horizontalAlignment = Alignment.End,
verticalArrangement = Arrangement.Bottom,
) {
if (!isShowingHistory) {
Spacer(modifier = Modifier.weight(1f))
}
InputResult(isCompact = isShowingHistory)
if (!isShowingHistory) {
Spacer(modifier = Modifier.weight(1f))
}
HistoryIconButton(
onClick = if (!isShowingHistory) showHistory else hideHistory,
modifier = Modifier.padding(16.dp),
)
}
}
}
}
It looks like this:
If isShowingHistory
is false
If isShowingHistory
is true
The appearance is correct. However, I want to animate the entrance of History
. One way I thought I could make that work is by using AnimatedVisibility
on the spacers. However, since the spacers use the modifier weight
, I cannot do that since weight
only works for direct children of the column.
@Composable
fun MainWindow(
isShowingHistory: Boolean,
showHistory: () -> Unit,
hideHistory: () -> Unit,
) {
Column(modifier = Modifier.fillMaxSize()) {
History(modifier = Modifier.weight(1f))
Surface(
color = contentColor.copy(0.04f),
modifier = Modifier.fillMaxWidth(),
) {
Column(
horizontalAlignment = Alignment.End,
verticalArrangement = Arrangement.Bottom,
) {
AnimatedVisibility(visible = !isShowingHistory) {
Spacer(modifier = Modifier.weight(1f))
}
InputResult(isCompact = isShowingHistory)
AnimatedVisibility(visible = !isShowingHistory) {
Spacer(modifier = Modifier.weight(1f))
}
HistoryIconButton(
onClick = if (!isShowingHistory) showHistory else hideHistory,
modifier = Modifier.padding(16.dp),
)
}
}
}
}
If isShowingHistory
is false
while using AnimatedVisibility
I have also tried moving the weight modifier to the AnimatedVisibility
like this:
@Composable
fun MainWindow(
isShowingHistory: Boolean,
showHistory: () -> Unit,
hideHistory: () -> Unit,
) {
Column(modifier = Modifier.fillMaxSize()) {
History(modifier = Modifier.weight(1f))
Surface(
color = contentColor.copy(0.04f),
modifier = Modifier.fillMaxWidth(),
) {
Column(
horizontalAlignment = Alignment.End,
verticalArrangement = Arrangement.Bottom,
) {
AnimatedVisibility(
visible = !isShowingHistory,
modifier = Modifier.weight(1f),
) {}
InputResult(isCompact = isShowingHistory)
AnimatedVisibility(
visible = !isShowingHistory,
modifier = Modifier.weight(1f),
) {}
HistoryIconButton(
onClick = if (!isShowingHistory) showHistory else hideHistory,
modifier = Modifier.padding(16.dp),
)
}
}
}
}
However, this does not animate the visibility of the spacers, even if I explicitly set the enter
and exit
parameters to expandVertically
and shrinkVertically
, since AnimatedVisibility
animates its contents, not itself.
How do I animate the weighted spacers? Or better yet, how do I properly animate the visibility of the History
composable, following the layout shown in the first two screenshots?
How about this solution
Short demo video
The main goal is to calc height and set it to History box. Let's say you wanted History takes 70% of the parent's height.
Full code:
History and InputResult boxes: