简体   繁体   中英

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

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? 在此处输入图像描述

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 eg 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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM