kopia lustrzana https://github.com/vitorpamplona/amethyst
104 wiersze
3.2 KiB
Kotlin
104 wiersze
3.2 KiB
Kotlin
package com.vitorpamplona.amethyst.ui.components
|
|
|
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
import androidx.compose.foundation.background
|
|
import androidx.compose.foundation.interaction.collectIsDraggedAsState
|
|
import androidx.compose.foundation.layout.Box
|
|
import androidx.compose.foundation.layout.Spacer
|
|
import androidx.compose.foundation.layout.fillMaxWidth
|
|
import androidx.compose.foundation.layout.padding
|
|
import androidx.compose.foundation.layout.size
|
|
import androidx.compose.foundation.layout.wrapContentHeight
|
|
import androidx.compose.foundation.layout.wrapContentWidth
|
|
import androidx.compose.foundation.lazy.LazyRow
|
|
import androidx.compose.foundation.pager.HorizontalPager
|
|
import androidx.compose.foundation.pager.PagerState
|
|
import androidx.compose.foundation.shape.CircleShape
|
|
import androidx.compose.material3.MaterialTheme
|
|
import androidx.compose.material3.Surface
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.getValue
|
|
import androidx.compose.ui.Alignment
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.draw.clip
|
|
import androidx.compose.ui.graphics.Color
|
|
import androidx.compose.ui.unit.Dp
|
|
import androidx.compose.ui.unit.dp
|
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
|
|
|
@OptIn(ExperimentalFoundationApi::class)
|
|
@Composable
|
|
fun SlidingCarousel(
|
|
pagerState: PagerState,
|
|
modifier: Modifier = Modifier,
|
|
itemContent: @Composable (index: Int) -> Unit
|
|
) {
|
|
val isDragged by pagerState.interactionSource.collectIsDraggedAsState()
|
|
|
|
Box(
|
|
modifier = modifier.fillMaxWidth()
|
|
) {
|
|
HorizontalPager(state = pagerState) { page ->
|
|
itemContent(page)
|
|
}
|
|
|
|
// you can remove the surface in case you don't want
|
|
// the transparant bacground
|
|
Surface(
|
|
modifier = Modifier
|
|
.padding(bottom = 8.dp)
|
|
.align(Alignment.BottomCenter),
|
|
shape = CircleShape,
|
|
color = Color.Black.copy(alpha = 0.5f)
|
|
) {
|
|
DotsIndicator(
|
|
modifier = Modifier.padding(horizontal = 8.dp, vertical = 6.dp),
|
|
totalDots = pagerState.pageCount,
|
|
selectedIndex = if (isDragged) pagerState.currentPage else pagerState.targetPage,
|
|
dotSize = 8.dp
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
fun DotsIndicator(
|
|
modifier: Modifier = Modifier,
|
|
totalDots: Int,
|
|
selectedIndex: Int,
|
|
selectedColor: Color = MaterialTheme.colorScheme.primary /* Color.Yellow */,
|
|
unSelectedColor: Color = MaterialTheme.colorScheme.placeholderText /* Color.Gray */,
|
|
dotSize: Dp
|
|
) {
|
|
LazyRow(
|
|
modifier = modifier
|
|
.wrapContentWidth()
|
|
.wrapContentHeight()
|
|
) {
|
|
items(totalDots) { index ->
|
|
IndicatorDot(
|
|
color = if (index == selectedIndex) selectedColor else unSelectedColor,
|
|
size = dotSize
|
|
)
|
|
|
|
if (index != totalDots - 1) {
|
|
Spacer(modifier = Modifier.padding(horizontal = 2.dp))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
fun IndicatorDot(
|
|
modifier: Modifier = Modifier,
|
|
size: Dp,
|
|
color: Color
|
|
) {
|
|
Box(
|
|
modifier = modifier
|
|
.size(size)
|
|
.clip(CircleShape)
|
|
.background(color)
|
|
)
|
|
}
|