Skip to content

Instantly share code, notes, and snippets.

@NakaoKisho
Last active May 11, 2024 08:08
Show Gist options
  • Select an option

  • Save NakaoKisho/0d3abae5fa09f753dfce681031955044 to your computer and use it in GitHub Desktop.

Select an option

Save NakaoKisho/0d3abae5fa09f753dfce681031955044 to your computer and use it in GitHub Desktop.
Accordion for Jetpack Compose
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
data class AccordionHeaderProp(
val modifier: Modifier = Modifier,
val onClick: () -> Unit,
val leadingIcon: @Composable (() -> Unit)? = null,
val trailingIcon: @Composable (() -> Unit)? = null,
val content: @Composable () -> Unit,
)
data class AccordionItemProp(
val modifier: Modifier = Modifier,
val accordionVisibilityAnimation: AccordionVisibilityAnimation,
val onClick: () -> Unit,
val leadingIcon: @Composable (() -> Unit)? = null,
val trailingIcon: @Composable (() -> Unit)? = null,
val content: @Composable () -> Unit,
)
data class AccordionVisibilityAnimation(
val visible: Boolean,
val modifier: Modifier = Modifier,
val enter: EnterTransition = fadeIn() + expandVertically(),
val exit: ExitTransition = fadeOut() + shrinkVertically(),
val label: String = "AnimatedVisibility",
)
@Composable
fun Accordion(
modifier: Modifier = Modifier,
verticalArrangement: Arrangement.Vertical,
accordionHeaderProp: AccordionHeaderProp,
accordionItemProps: List<AccordionItemProp>,
) {
Column(
modifier = modifier,
verticalArrangement = verticalArrangement
) {
AccordionItem(
modifier = accordionHeaderProp.modifier,
leadingIcon = accordionHeaderProp.leadingIcon,
trailingIcon = accordionHeaderProp.trailingIcon,
onClick = {
accordionHeaderProp.onClick()
},
content = accordionHeaderProp.content,
)
accordionItemProps.forEach { accordionItemProp ->
val visibilityAnimation = accordionItemProp.accordionVisibilityAnimation
AnimatedVisibility(
visible = accordionItemProp.accordionVisibilityAnimation.visible,
modifier = accordionItemProp.accordionVisibilityAnimation.modifier,
enter = visibilityAnimation.enter,
exit = visibilityAnimation.exit,
label = visibilityAnimation.label,
) {
AccordionItem(
modifier = accordionItemProp.modifier,
leadingIcon = accordionItemProp.leadingIcon,
trailingIcon = accordionItemProp.trailingIcon,
onClick = {
accordionItemProp.onClick()
},
content = accordionItemProp.content,
)
}
}
}
}
@Composable
private fun AccordionItem(
modifier: Modifier = Modifier,
leadingIcon: @Composable (() -> Unit)? = null,
trailingIcon: @Composable (() -> Unit)? = null,
onClick: () -> Unit,
content: @Composable () -> Unit,
) {
Row(
modifier = modifier
.clickable(
onClick = { onClick() }
),
verticalAlignment = Alignment.CenterVertically,
) {
if (leadingIcon != null) {
leadingIcon()
}
val maxWeight = 1f
AccordionTitle(
modifier = Modifier
.weight(
weight = maxWeight,
),
) {
content()
}
if (trailingIcon != null) {
trailingIcon()
}
}
}
@Composable
private fun AccordionTitle(
modifier: Modifier = Modifier,
content: @Composable () -> Unit,
) {
Box(
modifier = modifier,
) {
content()
}
}
@NakaoKisho

Copy link
Copy Markdown
Author

プレビューはブログに載せています
参考にされてください
I posted a preview code on my blog so feel free to check it!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment