Carousel
Yan yana duran slaytlar, biri ekranda: resimler, kartlar, bir tanıtımın adımları. Kaydırmak onları çevirir. Altındakiler carousel'in nerede olduğunu söyler ve ekrana dokunamayan okuyucu için slaytları çevirir.
import com.pantrixui.components.data.carousel.PantrixCarousel
- Göstergeler. Altında noktalar, bir sayaç ("2 / 4") ya da hiçbiri:
CarouselStyle.indicator. - Önceki ve sonraki düğmeleri. Platformun dokunarak kullanılmadığı yerde, masaüstünde ve masadaki tarayıcıda görünür, telefonun tarayıcısında görünmez. Belirleyen ekranın kullanıldığı işaretçidir, ekranın dokunmatik olup olmadığı değil: dokunmatik ekranlı bir dizüstünde de görünürler.
CarouselStyle.controlsonları her yerde gösterir ya da hiç göstermez. - Komşu slaytlar.
peekile iki yandaki slaytların kenarı görünür: bir kaydırmayla gelecek olan şimdiden bellidir. - Dönen slaytlar.
loopile sondan sonra ilki gelir. - Kendiliğinden ilerleme.
autoAdvanceMillisile carousel kendiliğinden ilerler; okuyucu bir slaydı tutarken, fare üstündeyken ve klavye odağı içindeyken bekler. Noktaların yanındaki düğme onu durdurur ve yeniden başlatır. Hareketin azaltıldığı temada kendiliğinden ilerlemez. - Slaydın üstünde.
CarouselPlacement.Overlaiddüğmeleri ve noktaları slaydın üstüne, kendi dolgusuna koyar: bir galeride yer kaplamazlar. - Yükseklik. Yükseklik verilen carousel'in slaytları noktalardan kalan yeri doldurur. Verilmeyen, ekrandaki slaydın yüksekliğindedir ve bir slayttan ötekine geçerken sıçramadan değişir.
- Dokunma. Noktalar parmak için tek bir hedeftir: sol yarısı bir geri, sağ yarısı bir ileri götürür; sağdan sola düzende yarılar yer değiştirir.
Örnekler
Öne çıkanlar: noktalarla
En yalın hâli: dört slayt ve altında noktalar. Slaydın sırası ekranın durumudur; carousel onu currentPage ile alır ve kaydırma bittiğinde onPageChange ile geri bildirir. Altındaki satır aynı durumu okur.
Yükseklik carousel'e verildi (180dp): slaytlar, noktalardan kalan yeri doldurur. Masaüstünde ve masadaki tarayıcıda iki yanda önceki ve sonraki düğmeleri de görünür; telefonda, tarayıcısında da, kaydırmak yeter.
var slide by rememberSaveable { mutableIntStateOf(0) }
PantrixCarousel(
pageCount = TITLES.size,
currentPage = slide,
onPageChange = { slide = it },
modifier = Modifier.height(180.dp),
contentDescription = "Öne çıkanlar",
tagKey = "featured"
) { index ->
CarouselSlide(index, modifier = Modifier.fillMaxSize())
}
PantrixText(text = "Ekranda: ${TITLES[slide]}", color = PantrixTheme.colors.textSecondary)
@Composable
private fun CarouselSlide(
index: Int,
modifier: Modifier = Modifier
) {
val role = roles()[index % ROLES]
PantrixSurface(modifier = modifier, color = role.container, contentColor = role.onContainer) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
PantrixText(text = TITLES[index % TITLES.size], style = PantrixTheme.typography.title)
}
}
}
@Composable
private fun roles(): List<PantrixColor> {
val colors = PantrixTheme.colors
return listOf(colors.info, colors.success, colors.warning, colors.danger)
}
private const val ROLES = 4
private val TITLES = listOf("Yeni gelenler", "Haftanın seçimi", "İndirimdekiler", "Son fırsat")
Komşuları görünen kartlar, sayaçla ve düğmelerle
peek = 24.dp ile slaytların iki yanında komşuları görünür: bir kaydırmayla gelecek olan şimdiden bellidir. indicator = CarouselIndicator.Count noktaların yerine bir sayaç yazar; controls = CarouselControls.Always düğmeleri telefonda da gösterir.
var slide by rememberSaveable { mutableIntStateOf(1) }
PantrixCarousel(
pageCount = TITLES.size,
currentPage = slide,
onPageChange = { slide = it },
contentDescription = "Teklifler",
style = CarouselStyle(
peek = 24.dp,
indicator = CarouselIndicator.Count,
controls = CarouselControls.Always
),
tagKey = "offers"
) { index ->
CarouselSlide(index, modifier = Modifier.fillMaxWidth().height(96.dp))
}
@Composable
private fun CarouselSlide(
index: Int,
modifier: Modifier = Modifier
) {
val role = roles()[index % ROLES]
PantrixSurface(modifier = modifier, color = role.container, contentColor = role.onContainer) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
PantrixText(text = TITLES[index % TITLES.size], style = PantrixTheme.typography.title)
}
}
}
private val TITLES = listOf("Yeni gelenler", "Haftanın seçimi", "İndirimdekiler", "Son fırsat")
@Composable
private fun roles(): List<PantrixColor> {
val colors = PantrixTheme.colors
return listOf(colors.info, colors.success, colors.warning, colors.danger)
}
private const val ROLES = 4
Kendi düğmesiyle ilerleyen tanıtım
Kaydırılmayan bir tanıtım: swipeEnabled = false, gösterge ve düğmeler de kapalı. Adımlar yalnızca "Devam" ile ilerler. Hangi adımda olunduğu ekranın kendi durumudur; düğme onu bir artırır, carousel oraya döner.
var step by rememberSaveable { mutableIntStateOf(0) }
val last = STEPS.lastIndex
PantrixCarousel(
pageCount = STEPS.size,
currentPage = step,
onPageChange = { step = it },
swipeEnabled = false,
contentDescription = "Tanıtım",
style = CarouselStyle(indicator = CarouselIndicator.None, controls = CarouselControls.Never),
tagKey = "introduction"
) { index ->
PantrixSurface(modifier = Modifier.fillMaxWidth(), border = PantrixTheme.colors.divider) {
PantrixText(text = STEPS[index], modifier = Modifier.padding(PantrixTheme.spacing.lg))
}
}
Row(
horizontalArrangement = Arrangement.spacedBy(PantrixTheme.spacing.md),
verticalAlignment = Alignment.CenterVertically
) {
PantrixButton(
text = if (step == last) "Baştan" else "Devam",
onClick = { step = if (step == last) 0 else step + 1 },
variant = ButtonVariant.Soft,
size = ButtonSize.Small,
tagKey = "introduction_next"
)
PantrixText(text = "Adım ${step + 1} / ${STEPS.size}", color = PantrixTheme.colors.textSecondary)
}
private val STEPS = listOf(
"Pantrix'e hoş geldin. Bu tanıtım üç adım sürer.",
"Bileşenler her platformda aynı tasarım dilini konuşur.",
"Hazırsın: bileşen listesine dönüp birini açabilirsin."
)
Bir dolgunun üstünde
Temanın zemini olmayan bir dolgunun üstünde carousel. Renk verilmedi: dolgu, üstüne ne renkle yazıldığını söyler. Ekrandaki slaydın noktası ve düğmeler o renkte, öteki noktalar onun bir payındadır.
var slide by rememberSaveable { mutableIntStateOf(0) }
PantrixSurface(modifier = Modifier.fillMaxWidth(), color = PantrixTheme.colors.primary.color) {
PantrixCarousel(
pageCount = 3,
currentPage = slide,
onPageChange = { slide = it },
modifier = Modifier.padding(PantrixTheme.spacing.md),
contentDescription = "Dolgu üstünde",
style = CarouselStyle(controls = CarouselControls.Always),
tagKey = "filled"
) { index ->
CarouselSlide(index, modifier = Modifier.fillMaxWidth().height(72.dp))
}
}
@Composable
private fun CarouselSlide(
index: Int,
modifier: Modifier = Modifier
) {
val role = roles()[index % ROLES]
PantrixSurface(modifier = modifier, color = role.container, contentColor = role.onContainer) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
PantrixText(text = TITLES[index % TITLES.size], style = PantrixTheme.typography.title)
}
}
}
@Composable
private fun roles(): List<PantrixColor> {
val colors = PantrixTheme.colors
return listOf(colors.info, colors.success, colors.warning, colors.danger)
}
private const val ROLES = 4
private val TITLES = listOf("Yeni gelenler", "Haftanın seçimi", "İndirimdekiler", "Son fırsat")
Kendiliğinden dönen galeri
Resim galerisi gibi: loop ile slaytlar döner, autoAdvanceMillis ile altı saniyede bir kendiliğinden ilerler. placement = CarouselPlacement.Overlaid düğmeleri ve noktaları slaydın üstüne, carousel'in kendi dolgusuna koyar (açık temada koyu, koyu temada açık); yer kaplamazlar.
Noktaların yanındaki düğme dönmeyi durdurur ve yeniden başlatır. Bir slaydı tutarken, fare üstündeyken ve klavye odağı içindeyken carousel kendiliğinden bekler.
var slide by rememberSaveable { mutableIntStateOf(0) }
PantrixCarousel(
pageCount = TITLES.size,
currentPage = slide,
onPageChange = { slide = it },
modifier = Modifier.height(200.dp),
contentDescription = "Galeri",
loop = true,
autoAdvanceMillis = GALLERY_MILLIS,
style = CarouselStyle(controls = CarouselControls.Always, placement = CarouselPlacement.Overlaid),
tagKey = "gallery"
) { index ->
CarouselSlide(index, modifier = Modifier.fillMaxSize())
}
@Composable
private fun CarouselSlide(
index: Int,
modifier: Modifier = Modifier
) {
val role = roles()[index % ROLES]
PantrixSurface(modifier = modifier, color = role.container, contentColor = role.onContainer) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
PantrixText(text = TITLES[index % TITLES.size], style = PantrixTheme.typography.title)
}
}
}
private val TITLES = listOf("Yeni gelenler", "Haftanın seçimi", "İndirimdekiler", "Son fırsat")
private const val GALLERY_MILLIS = 6_000
@Composable
private fun roles(): List<PantrixColor> {
val colors = PantrixTheme.colors
return listOf(colors.info, colors.success, colors.warning, colors.danger)
}
private const val ROLES = 4
Farklı yükseklikte slaytlar
Slaytların yüksekliği birbirinden farklı ve carousel'e yükseklik verilmemiş. Carousel ekrandaki slaydın yüksekliğindedir; bir slayttan ötekine geçerken yüksekliği de onunla birlikte, sıçramadan değişir. Altındaki satır bunu gösterir: slaytla birlikte aşağı ve yukarı kayar.
var slide by rememberSaveable { mutableIntStateOf(0) }
PantrixCarousel(
pageCount = NOTES.size,
currentPage = slide,
onPageChange = { slide = it },
contentDescription = "Notlar",
loop = true,
tagKey = "notes"
) { index ->
PantrixSurface(modifier = Modifier.fillMaxWidth(), border = PantrixTheme.colors.divider) {
PantrixText(text = NOTES[index], modifier = Modifier.padding(PantrixTheme.spacing.lg))
}
}
PantrixText(
text = "Bu satır, slaytların yüksekliğiyle birlikte yer değiştirir.",
color = PantrixTheme.colors.textSecondary
)
private val NOTES = listOf(
"Kısa bir not.",
"Daha uzun bir not: birkaç satır sürer, çünkü anlatacak daha çok şeyi vardır. Carousel bu slayda gelirken " +
"yüksekliği de yavaş yavaş artar; altındaki satır aşağı kayar.",
"Orta boy bir not, iki satır kadar tutar ve öncekinden kısadır."
)
Kendi renkleriyle
Kendi renkleriyle: CarouselColors noktaları, noktaların izini, düğmeleri ve slaytın üstündeki örtüyü boyar. Burada noktalar markanın değil başarının rengindedir; verilmeyen her renk temanınkidir.
var slide by rememberSaveable { mutableIntStateOf(0) }
PantrixCarousel(
pageCount = TITLES.size,
currentPage = slide,
onPageChange = { slide = it },
modifier = Modifier.height(160.dp),
colors = CarouselColors(
indicator = PantrixTheme.colors.success.color,
indicatorTrack = PantrixTheme.colors.success.container,
control = PantrixTheme.colors.success.color
),
contentDescription = "Öne çıkanlar",
tagKey = "green"
) { index ->
CarouselSlide(index, modifier = Modifier.fillMaxSize())
}
@Composable
private fun CarouselSlide(
index: Int,
modifier: Modifier = Modifier
) {
val role = roles()[index % ROLES]
PantrixSurface(modifier = modifier, color = role.container, contentColor = role.onContainer) {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
PantrixText(text = TITLES[index % TITLES.size], style = PantrixTheme.typography.title)
}
}
}
@Composable
private fun roles(): List<PantrixColor> {
val colors = PantrixTheme.colors
return listOf(colors.info, colors.success, colors.warning, colors.danger)
}
private const val ROLES = 4
private val TITLES = listOf("Yeni gelenler", "Haftanın seçimi", "İndirimdekiler", "Son fırsat")
API
pageCount
Yan yana duran slaytlar, biri ekranda: resimler, kartlar, bir tanıtımın adımları. Kaydırmak onları çevirir. Altındakiler carousel'in nerede olduğunu söyler ve ekrana dokunamayan okuyucu için slaytları çevirir.
| Parametre | Tür | Varsayılan | Ne olduğu |
|---|---|---|---|
pageCount | Int | Kaç slayt olduğu. | |
currentPage | Int | Ekrandaki slayt, bir sayfalayıcınınki gibi sıfırdan sayılır. Uçlardan birinin ötesindeki değer en yakın slayt sayılır. PantrixPagination sayfalarını, yazdığı gibi, birden sayar: onun sayfası bunun bir fazlasıdır. | |
onPageChange | (page: Int) -> Unit | Bir kaydırmanın bittiği slayt ve bir düğmenin, bir noktanın, bir tuşun ya da kendiliğinden ilerlerken carousel'in istediği slayt bildirilir. | |
modifier | Modifier | Modifier | Carousel'e uygulanır: slaytlara ve altındakilere. |
contentDescription | String? | null | Ekran okuyucu için carousel'in içinde ne olduğu: "Öne çıkan ürünler". |
swipeEnabled | Boolean | true | Kaydırmanın slaytları çevirip çevirmediği. Kendi düğmesiyle ilerleyen bir tanıtım bunu kapatır. |
loop | Boolean | false | Slaytların dönüp dönmediği: sonuncudan ilkine geçilir. Tek slaytlı bir carousel'in gidecek yeri yoktur. |
autoAdvanceMillis | Int | 0 | Carousel'in kendiliğinden sonrakine geçmeden önce bir slaytta ne kadar kaldığı. Yalnızca okuyucusunun çevirdiği bir carousel için sıfırdır. Bir slaydı okumaya yetecek kadar uzun verilir: beş saniye ya da daha fazla. |
style | CarouselStyle? | null | Bu çağrının kendi stili: çevresindeki her stili ezer, yoğunluk ona da uygulanır. Yalnızca verdiği alanlar değişir ve her platformda değişir. |
colors | CarouselColors? | null | Bu çağrının, slaytların altındakiler için kendi renkleri. Yalnızca verdiği renkler değişir. |
tagKey | String? | null | Otomasyon için dilden bağımsız bir anahtar: carousel'in etiketi Carousel_<tagKey> olur ve parçaları onun içinde adlandırılır: klavye odağını alan Carousel_<tagKey>.Slides_view, .Page_<index>, .Control_previous, .Control_next, .Control_pause ve .Indicator_position. Slaytların döndüğü ve komşu slaytların göründüğü yerde iki slaytlı bir carousel'de aynı slayt iki yanda birden durur: aynı etiketle iki kez. |
page | @Composable (index: Int) -> Unit | Sırasına göre bir slayt. |
CarouselStyle
PantrixCarousel'in geometrisi ve slaytlarının altında ne gösterdiği. Her platformda aynıdır: düğmeler platforma göre değil, okuyucunun parmakla mı fareyle mi kullandığına göre gelir ve gider. Boşluklar yoğunlukla ölçeklenir, nokta ölçeklenmez.
| Parametre | Tür | Varsayılan | Ne olduğu |
|---|---|---|---|
pageSpacing | Dp | Dp.Unspecified | İki slaydın arasındaki boşluk. Bir slayt yerini sonrakine bırakırken ve komşuları peek ile görünen bir slaydın yanında görünür. |
peek | Dp | Dp.Unspecified | Ekrandaki slaydın iki yanında bırakılan yer: komşuları bu yerde görünür. |
indicatorSize | Dp | Dp.Unspecified | Göstergenin bir noktası. |
indicatorGap | Dp | Dp.Unspecified | İki noktanın arası. |
indicatorSpacing | Dp | Dp.Unspecified | Slaytlarla altındakilerin arası. Altındakiler slaytların üstünde duruyorsa onlarla slaytların kenarlarının arası. |
indicator | CarouselIndicator? | null | Carousel'in nerede olduğunu neyin söylediği. |
controls | CarouselControls? | null | İki düğmenin nerede gösterildiği. |
placement | CarouselPlacement? | null | Bunların slaytların altında mı, üstünde mi durduğu. |
CarouselColors
Temanın renklerini almayan bir carousel için PantrixCarousel'in slaytlarının altında neyle boyandığı: verilen renk kullanılır, verilmeyen temanınki olarak kalır. Slaytlar çağıranın kendisinindir.
| Parametre | Tür | Varsayılan | Ne olduğu |
|---|---|---|---|
indicator | Color | Color.Unspecified | Ekrandaki slaydın noktası. primary rolünün color'ı. |
indicatorTrack | Color | Color.Unspecified | Öteki slaytların noktaları. Temanın borderStrong'u: bir kontrolün kendi işareti gibi zeminden ayırt edilir. |
control | Color | Color.Unspecified | Düğmeler. Temanın onSurface'ı, bir ikonun rengi. |
overlay | Color | Color.Unspecified | Slaytların üstünde durduklarında noktaların ve her düğmenin arkasındaki dolgu. Temanın onSurface'ı: temanın zeminlerinin ters tonu, slayt arkasından görünsün diye saydamlaştırılmış. Buraya temanın rol renklerinden biri verilirse, üstüne yazılanlar için temanın onunla eşleştirdiği renk de gelir. |
Erişilebilirlik
- Klavye. Slaytlar tek bir duraktır: ok tuşları çevirir, Home ve End başa ve sona götürür.
- Ekran okuyucu. Nerede olunduğunu her değişimde söyler: "Slayt 2 / 4". Kendiliğinden ilerleyen carousel her geçişte araya girmez.