google / accompanist

A collection of extension libraries for Jetpack Compose
https://google.github.io/accompanist
Apache License 2.0
7.4k stars 596 forks source link

[Pager] #1376

Closed selena775 closed 1 year ago

selena775 commented 1 year ago

Description Using HorizontalPager with PaddingValues large enough so that 5 pages are visible, like a carousel. When on fling stops, page, next to the one in center, snaps. If fling is on the left the left page snaps. If it is on right, the right one snaps. I would expect that scroller scrolls, but always the center page snaps. This happens only when the scrolling is slow.

Steps to reproduce Create HorizontalPager with PaddingValues 140.dp. Pass an array of 5 numbers. And add Text as a container layout that will show the number. Fling on right. The page right to the center one will snap Fling on left. The page left to the center one will snap

Expected behavior On Fling, there is scrolling. When scrolling finishes, the center page snaps.

Additional context Maybe a solution would be to give developer opportunity to disable snap(spring) animation all together as page content can be animated anyway

andkulikov commented 1 year ago

can you please show a screenshot for what do you mean by "5 pages are visible". also if you can provide a full code for the sample it could be easier for us to reproduce.

selena775 commented 1 year ago

I've added font size and transparency myself. But the problem is snap on stop that I can't prevent

On Thu, Oct 20, 2022 at 8:21 PM Andrey Kulikov @.***> wrote:

can you please show a screenshot for what do you mean by "5 pages are visible". also of you can provide a full code for the sample it could be easier for us to reproduce.

— Reply to this email directly, view it on GitHub https://github.com/google/accompanist/issues/1376#issuecomment-1285212476, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABZZWMKB4FYZ6RB4Y3FPHXTWEEFLBANCNFSM6AAAAAARJZEQBM . You are receiving this because you authored the thread.Message ID: @.***>

selena775 commented 1 year ago

StepSliderAccompanist(listOf("5","10","15","20","25"))

@Composable fun StepSliderAccompanist(labelList: List) { val textColor = WxTheme.colorScheme.primary

BoxWithConstraints( // modifier = Modifier // .border( // BorderStroke(1.dp, SolidColor(textColor)), // shape = (RoundedCornerShape(2.dp)) // ) ) {

HorizontalPager( count = labelList.size, contentPadding = PaddingValues(horizontal = 150.dp) ) { page -> // ...page content val pageOffset = calculateCurrentOffsetForPage(page).absoluteValue

val alphaStart: Float val alphaEnd: Float val scaleStart: Float val scaleEnd: Float val fraction: Float

if (pageOffset > 1) { fraction = 2f - pageOffset.coerceIn(0f, 2f) alphaStart = 0.75f alphaEnd = 0.85f scaleStart = 0.75f scaleEnd = 0.85f } else { fraction = 1f - pageOffset.coerceIn(0f, 1f) alphaStart = 0.85f alphaEnd = 1f scaleStart = 0.85f scaleEnd = 1f } Text( modifier = Modifier .padding(8.dp) .graphicsLayer { // Calculate the absolute offset for the current page from the // scroll position. We use the absolute value which allows us to mirror // any effects for both directions

// We animate the scaleX + scaleY, between 85% and 100% androidx.compose.ui.layout .lerp( start = ScaleFactor(scaleX = scaleStart, scaleY = scaleStart), stop = ScaleFactor(scaleX = scaleEnd, scaleY = scaleEnd), fraction = fraction ) .also { scale -> scaleX = scale.scaleX scaleY = scale.scaleY }

// We animate the alpha, between 50% and 100% androidx.compose.ui.graphics .lerp( start = textColor.copy(alpha = alphaStart), stop = textColor.copy(alpha = alphaEnd), fraction = fraction ) .also { color -> alpha = color.alpha } }, text = labelList[page], style = TextStyle( color = textColor.copy(alpha = alphaEnd), fontSize = 32.sp * scaleEnd ) )

}

Box( Modifier .align(Alignment.TopCenter) .height(6.dp) .width(1.dp) .background(Color.Blue) )

Box( Modifier .align(Alignment.BottomCenter) .height(6.dp) .width(1.dp) .background(Color.Blue) ) } }

On Thu, Oct 20, 2022 at 8:39 PM Selena Klasnja @.***> wrote:

I've added font size and transparency myself. But the problem is snap on stop that I can't prevent

On Thu, Oct 20, 2022 at 8:21 PM Andrey Kulikov @.***> wrote:

can you please show a screenshot for what do you mean by "5 pages are visible". also of you can provide a full code for the sample it could be easier for us to reproduce.

— Reply to this email directly, view it on GitHub https://github.com/google/accompanist/issues/1376#issuecomment-1285212476, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABZZWMKB4FYZ6RB4Y3FPHXTWEEFLBANCNFSM6AAAAAARJZEQBM . You are receiving this because you authored the thread.Message ID: @.***>

andkulikov commented 1 year ago

Maybe then providing video is better. without that I can't understand what you are trying to active

Snapping after finishing scrolling is a core feature of a Pager. Maybe you want to just use LazyRow instead?

selena775 commented 1 year ago

Yes, but I need to implement stopping at the points only. I hoped there would be a ready solution.

On Thu, Oct 20, 2022 at 8:45 PM Andrey Kulikov @.***> wrote:

Maybe then providing video is better. without that I can't understand what you are trying to active

Snapping after finishing scrolling is a core feature of a Pager. Maybe you want to just use LazyRow instead?

— Reply to this email directly, view it on GitHub https://github.com/google/accompanist/issues/1376#issuecomment-1285241935, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABZZWMOWM4NC2WO4NSHNRBDWEEIFDANCNFSM6AAAAAARJZEQBM . You are receiving this because you authored the thread.Message ID: @.***>

andkulikov commented 1 year ago

Hm, but from the video I can see that it is already stopping only on the points with the text. it is what we call snapping. What do you expect instead?

selena775 commented 1 year ago

Stopping is fine, but after stopping, there is a zoom in or scale anmation on number left or right, depending on direction. Look at the video. It stopped at 15, but 10 snapped. Then it stopped on 10, but 5 snapped.

https://user-images.githubusercontent.com/7576369/196933686-026b1a4b-f70e-4660-aca3-86f1bf5c43d5.mp4

selena775 commented 1 year ago

I think this is not a functionality you planned this library would be used for. I will listen to your advice and use LazyRow and slider correction to stop only on given points. But please let me be know if you maybe have a component I might use out of the box for this kind of a problem. Thank you so much.

andkulikov commented 1 year ago

No, in fact you are not doing anything wrong conceptually. I think it is just some mistake in the scale offset calculation

selena775 commented 1 year ago

You are right. I removed again all my animation code and everything works perfectly fine. I will figure it out what I do wrong. Thank you so much. I will close this ticket as it has nothing to do with library.

selena775 commented 1 year ago

Oh dear, I found where was the problem in my code. Line

if (pageOffset > 1) {
    fraction = 2f - pageOffset.coerceIn(0f, 2f)
    ...
}

should have been

if (pageOffset > 1) {
    fraction = 2f - pageOffset.coerceIn(1f, 2f)
    ...
}

I will be testing a bit more, maybe do it in a different way, but this is a really great library. Thank you