Add a revered parameter to AvatarRow to be able to stack avatar the other way.
This commit is contained in:
parent
333b1c8a48
commit
324fc28e2d
1 changed files with 53 additions and 9 deletions
|
|
@ -38,6 +38,7 @@ import kotlinx.collections.immutable.toImmutableList
|
||||||
* @param modifier Jetpack Compose modifier
|
* @param modifier Jetpack Compose modifier
|
||||||
* @param overlapRatio the overlap ration. When 0f, avatars will render without overlap, when 1f
|
* @param overlapRatio the overlap ration. When 0f, avatars will render without overlap, when 1f
|
||||||
* only the first avatar will be visible
|
* only the first avatar will be visible
|
||||||
|
* @param lastOnTop if true, the last visible avatar will be rendered on top.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun AvatarRow(
|
fun AvatarRow(
|
||||||
|
|
@ -45,6 +46,7 @@ fun AvatarRow(
|
||||||
avatarType: AvatarType,
|
avatarType: AvatarType,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
overlapRatio: Float = 0.5f,
|
overlapRatio: Float = 0.5f,
|
||||||
|
lastOnTop: Boolean = false,
|
||||||
) {
|
) {
|
||||||
val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
|
val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
|
||||||
Box(
|
Box(
|
||||||
|
|
@ -54,23 +56,35 @@ fun AvatarRow(
|
||||||
val avatarSize = avatarDataList.firstOrNull()?.size?.dp ?: return
|
val avatarSize = avatarDataList.firstOrNull()?.size?.dp ?: return
|
||||||
val avatarSizePx = avatarSize.toPx()
|
val avatarSizePx = avatarSize.toPx()
|
||||||
avatarDataList
|
avatarDataList
|
||||||
.reversed()
|
.let {
|
||||||
|
if (lastOnTop) {
|
||||||
|
it
|
||||||
|
} else {
|
||||||
|
it.reversed()
|
||||||
|
}
|
||||||
|
}
|
||||||
.forEachIndexed { index, avatarData ->
|
.forEachIndexed { index, avatarData ->
|
||||||
|
val startPadding = if (lastOnTop) {
|
||||||
|
avatarSize * (1 - overlapRatio) * index
|
||||||
|
} else {
|
||||||
|
avatarSize * (1 - overlapRatio) * (lastItemIndex - index)
|
||||||
|
}
|
||||||
Avatar(
|
Avatar(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(start = avatarSize * (1 - overlapRatio) * (lastItemIndex - index))
|
.padding(start = startPadding)
|
||||||
.graphicsLayer {
|
.graphicsLayer {
|
||||||
compositingStrategy = CompositingStrategy.Offscreen
|
compositingStrategy = CompositingStrategy.Offscreen
|
||||||
}
|
}
|
||||||
.drawWithContent {
|
.drawWithContent {
|
||||||
// Draw content and clear the pixels for the avatar on the left (right in RTL).
|
// Draw content and clear the pixels for the avatar on the left (right in RTL) or when lastOnTop is true on
|
||||||
|
// the right (left in RTL).
|
||||||
drawContent()
|
drawContent()
|
||||||
val xOffset = if (isRtl) {
|
|
||||||
size.width - avatarSizePx * (overlapRatio - 0.5f)
|
|
||||||
} else {
|
|
||||||
0f + avatarSizePx * (overlapRatio - 0.5f)
|
|
||||||
}
|
|
||||||
if (index < lastItemIndex) {
|
if (index < lastItemIndex) {
|
||||||
|
val xOffset = if (isRtl == lastOnTop) {
|
||||||
|
avatarSizePx * (overlapRatio - 0.5f)
|
||||||
|
} else {
|
||||||
|
size.width - avatarSizePx * (overlapRatio - 0.5f)
|
||||||
|
}
|
||||||
drawCircle(
|
drawCircle(
|
||||||
color = Color.Black,
|
color = Color.Black,
|
||||||
center = Offset(
|
center = Offset(
|
||||||
|
|
@ -101,6 +115,17 @@ internal fun AvatarRowPreview(@PreviewParameter(OverlapRatioProvider::class) ove
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
@PreviewsDayNight
|
||||||
|
internal fun AvatarRowLastOnTopPreview(@PreviewParameter(OverlapRatioProvider::class) overlapRatio: Float) {
|
||||||
|
ElementPreview {
|
||||||
|
ContentToPreview(
|
||||||
|
overlapRatio = overlapRatio,
|
||||||
|
lastOnTop = true,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@PreviewsDayNight
|
@PreviewsDayNight
|
||||||
internal fun AvatarRowRtlPreview(@PreviewParameter(OverlapRatioProvider::class) overlapRatio: Float) {
|
internal fun AvatarRowRtlPreview(@PreviewParameter(OverlapRatioProvider::class) overlapRatio: Float) {
|
||||||
|
|
@ -114,7 +139,25 @@ internal fun AvatarRowRtlPreview(@PreviewParameter(OverlapRatioProvider::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ContentToPreview(overlapRatio: Float) {
|
@PreviewsDayNight
|
||||||
|
internal fun AvatarRowLastOnTopRtlPreview(@PreviewParameter(OverlapRatioProvider::class) overlapRatio: Float) {
|
||||||
|
CompositionLocalProvider(
|
||||||
|
LocalLayoutDirection provides LayoutDirection.Rtl,
|
||||||
|
) {
|
||||||
|
ElementPreview {
|
||||||
|
ContentToPreview(
|
||||||
|
overlapRatio = overlapRatio,
|
||||||
|
lastOnTop = true,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ContentToPreview(
|
||||||
|
overlapRatio: Float,
|
||||||
|
lastOnTop: Boolean = false,
|
||||||
|
) {
|
||||||
AvatarRow(
|
AvatarRow(
|
||||||
avatarDataList = listOf("A", "B", "C").map {
|
avatarDataList = listOf("A", "B", "C").map {
|
||||||
AvatarData(
|
AvatarData(
|
||||||
|
|
@ -125,5 +168,6 @@ private fun ContentToPreview(overlapRatio: Float) {
|
||||||
}.toImmutableList(),
|
}.toImmutableList(),
|
||||||
avatarType = AvatarType.User,
|
avatarType = AvatarType.User,
|
||||||
overlapRatio = overlapRatio,
|
overlapRatio = overlapRatio,
|
||||||
|
lastOnTop = lastOnTop,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue