Home > Blockchain >  How to set visible indicator' dot and show the others when scrolling in jetpack compose
How to set visible indicator' dot and show the others when scrolling in jetpack compose

Time:08-28

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? enter image description here

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.

  • Related