I have a lazyRow and I want to show list of indicators:
what I want: I want to show 6 items and when user scrolls other indicators get visible.
@Composable
private fun ImagesDotsIndicator(
modifier: Modifier,
totalDots: Int,
selectedIndex: Int
) {
LazyRow(
modifier = modifier,
horizontalArrangement = Arrangement.Center,
reverseLayout = true,
verticalAlignment = Alignment.CenterVertically
) {
if (totalDots == 1) return@LazyRow
items(totalDots) { index ->
if (index == selectedIndex) {
Box(
modifier = Modifier
.size(8.dp)
.clip(CircleShape)
.background(color = Color.White)
)
} else {
Box(
modifier = Modifier
.size(6.dp)
.clip(CircleShape)
.background(color = Color.LightGray)
)
}
Spacer(modifier = Modifier.padding(horizontal = 2.dp))
}
}
}
how can I make this indicator?
CodePudding user response:
I would suggest you use Google's Accompanist HorizontalPager and HorizontalPagerIndicator if you want to swipe pages and show the dots. This is a layout that lays out items in a horizontal row, and allows the user to horizontally swipe between pages and also show the page indicator.
You need to add these 2 lines to your app build gradle file to add the dependencies.
// Horizontal Pager and Indicators - Accompanist
implementation "com.google.accompanist:accompanist-pager:0.24.7-alpha"
implementation "com.google.accompanist:accompanist-pager-indicators:0.24.7-alpha"
On your composable file, you can add a simple Sealed class to hold the data that you want to display e.g. text.
sealed class CustomDisplayItem(val text1:String, val text2: String){
object FirstItem: CustomDisplayItem("Hi", "World")
object SecondItem: CustomDisplayItem("Hello", "I'm John")
}
Thereafter make a template of the composable element or page that you want to show if the user swipes left or right.
@Composable
fun DisplayItemTemplate(item: CustomDisplayItem) {
Column() {
Text(text = item.text2 )
Spacer(modifier = Modifier.height(4.dp))
Text(text = item.text2)
}
}
Lastly use HorizontalPager
and HorizontalPageIndicator
composables to display the corresponding page when a user swipes back and forth.
@OptIn(ExperimentalPagerApi::class)
@Composable
fun ImagesDotsIndicator(
modifier: Modifier,
) {
//list of pages to display
val displayItems = listOf(CustomDisplayItem.FirstItem, CustomDisplayItem.SecondItem)
val state = rememberPagerState()
Column(modifier = modifier.fillMaxSize()) {
//A horizontally scrolling layout that allows users to
// flip between items to the left and right.
HorizontalPager(
count = 6,
state = state,
) {
/*whenever we scroll sideways the page variable changes
displaying the corresponding page */
item ->
//call template item and add the data
DisplayItemTemplate(item = displayItems[item])
}
//HorizontalPagerIndicator dots
HorizontalPagerIndicator(
pagerState = state,
activeColor = MaterialTheme.colors.primary,
inactiveColor = Color.Gray,
indicatorWidth = 16.dp,
indicatorShape = CircleShape,
spacing = 8.dp,
modifier = Modifier
.weight(.1f)
.align(CenterHorizontally)
)
}
}
Please see the above links to read more on how you can customize your composables to work in your case.
CodePudding user response:
Actually it is preaty straight forward without any additional library:
val list = (0..100).toList()
val state = rememberLazyListState()
val visibleIndex by remember {
derivedStateOf {
state.firstVisibleItemIndex
}
}
Text(text = visibleIndex.toString())
LazyColumn(state = state) {
items(list) { item ->
Text(text = item.toString())
}
}
Create scroll state and use it on your list, and on created scroll state observe first visible item.