How to snap scrollable items to center of screen in Jetpack Compose

How to snap scrollable items to center of screen in Jetpack Compose

Snapper migrated fromSnapFlingBehavior
article logo

Previously, we explored a common use case in Android app development: snapping scrollable items to the center of the screen after a fling gesture.

To achieve this in Jetpack Compose we use the previously archived "Snapper" library. Snapper provides a seamless solution for implementing snapping behavior in scrollable layouts when the official framework does not yet support it. If you missed that article, you can read it here.

Jetpack Compose has grown since then, and the good news is that the functionality we previously implemented using the Snapper library is now officially supported in Jetpack Compose, introducing SnapFlingBehavior. This new class provides a more comprehensive and efficient solution for centering items in scrollable lists with dynamic content.

In this article, we'll revisit the issues we tackled in previous articles and demonstrate how to transition from using the Snapper library to the officially supported one SnapFlingBehavior. We'll start by discussing the main differences between the two approaches, and then provide a step-by-step guide for implementing it in a Jetpack Compose project SnapFlingBehavior.

Convert to SnapFlingBehavior

For a quick recap, let's take a look at the core functionality we implement with Snapper. This library allows us to create a dynamic scrollable list that snaps items to the center of the screen after a fling gesture. When Jetpack Compose doesn't have a feature that officially implements this use case, it's a great solution.
With the introduction SnapFlingBehavior, we can now implement this snapping behavior using Jetpack Compose's official API. SnapFlingBehaviorProvides greater flexibility and customization options than the Snapper library .
SnapFlingBehaviorClass to make items snap to a given position, using shortSnapVelocityThresholda parameter to differentiate between short/scroll snaps and long/fling snaps. In addition, it provides various animation specifications for different situations, such as highVelocityAnimationSpec, , lowVelocityAnimationSpecand snapAnimationSpec.
Now let's see how we can leverage SnapFlingBehavior to achieve the same functionality we achieved earlier using the Snapper library.

Revisiting our previous use cases

In my last article on the Snapper library, we used an example of a dynamic list:

@Composable
fun MainContent(
    placeholderItems: List<String>
) {
    
    

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
    
    

        Text(
            modifier = Modifier
                .padding(16.dp)
                .fillMaxWidth(),
            text = "Example Horizontal LazyRow"
        )

        LazyRow(
            modifier = Modifier.fillMaxWidth(),
            contentPadding = PaddingValues(8.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
    
    
            items(items = placeholderItems) {
    
     itemMessage: String ->
                PlaceholderCard(itemMessage)
            }
        }
    }
}

The actual effect is as follows:
LazyRow default behavior
we can use Snapper to achieve fling behavior, as shown in the following code snippet:

val lazyListState: LazyListState = rememberLazyListState()
  val layoutInfo: LazyListSnapperLayoutInfo = rememberLazyListSnapperLayoutInfo(lazyListState)

  LazyRow(
      modifier = Modifier.fillMaxWidth(),
      state = lazyListState,
      flingBehavior = rememberSnapperFlingBehavior(lazyListState),
      contentPadding = PaddingValues(8.dp),
      verticalAlignment = Alignment.CenterVertically,
  ) {
    
    
      items(items = placeholderItems) {
    
     itemMessage: String ->
          PlaceholderCard(itemMessage)
      }
  }

Use SnapFlingBehavior

However, to ensure that visible items scroll to the center of the screen after performing a fling gesture, we no longer need to rely on external libraries. Instead, we can leverage what was discussed earlier SnapFlingBehavior.

The following code snippet shows SnapFlingBehavior enabled MainContent:

@Composable
fun MainContent(
    placeholderItems: List<String>
) {
    
    

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
    
    

        Text(
            modifier = Modifier
                .padding(16.dp)
                .fillMaxWidth(),
            text = "Example Horizontal LazyRow"
        )

        val listState: LazyListState = rememberLazyListState()

        LazyRow(
            modifier = Modifier.fillMaxWidth(),
            contentPadding = PaddingValues(horizontal = 32.dp),
            verticalAlignment = Alignment.CenterVertically,
            state = listState,
            flingBehavior = rememberSnapFlingBehavior(listState)
        ) {
    
    
            items(placeholderItems) {
    
     item: String ->
                PlaceholderCard(itemMessage = item)
            }
        }
    }
}

First, we rememberLazyListState()create one using functions LazyListState, which allow us to store and manage our LazyRowcomponent's state:

val listState: LazyListState = rememberLazyListState()

Next, we defined LazyRowthe component :

  • modifier = Modifier.fillMaxWidth(): Make sure LazyRowthat spans the entire width of the screen.
  • contentPadding = PaddingValues(horizontal = 32.dp): Applies a padding of 32.dp horizontally LazyRow inside the .
  • verticalAlignment = Alignment.CenterVertically: LazyRowCenters the items in the vertically.
  • state = listState: LazyListStateSets to LazyRowthe state of .
  • flingBehavior = rememberSnapFlingBehavior(listState): By providing listState, SnapFlingBehaviorassign to LazyRowso that the items in the list snap to the center after a fling gesture and finally achieve the desired behavior.

The final effect is as follows:
LazyRow with SnapFlingBehavior

in conclusion

In this article, we revisited the issue of snapping scrollable items to the center of the screen in Jetpack Compose and switched from using the Snapper library to the officially supported one SnapFlingBehavior.
We first saw how we previously implemented dynamic, scrollable lists that automatically snap items to the center of the screen after a gesture swipe. Subsequently, we discussed the same method using the official solution. In the end, we found that the difference in code length was not huge and the migration process was very simple.

Guess you like

Origin blog.csdn.net/u011897062/article/details/130560043