Image Transition with Animation in Jetpack Compose

Introduction

The use of animation in UI creation has been made incredibly simple with Jetpack Compose. In this article, we'll have a look at a new approach to displaying photos with Jetpack Compose's image transition, which is a simple animation.

We will be using the free 'gstatic' images API to fetch images online and show them using the coil library. So without wasting any time, let's get started.

Setup

Add the dependency in 'app/build.gradle'.

implementation "io.coil-kt:coil-compose:2.3.0"

Consider adding the latest dependency of the coil. You can the latest dependency here https://coil-kt.github.io/coil/compose/

and don't forget to add the internet permission in the AndroidManifest.xml file.

<uses-permission android:name="android.permission.INTERNET"/>

Now with the above setup, let's move towards the Our Goal with the following steps.

Step 1. JetPack Compose new project

Create a new Project in JetPack Compose, and in the main activity, delete some existing code and place a new composable function ImageScreen() as the below code.

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            GalleryTransitionAppTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    ImageScreen()
                }
            }
        }
    }
}

Step 2. ImageScreen Composable function

The provided code creates the 'ImageScreen' Composable function using the experimental 'ExperimentalMaterial3Api' and 'ExperimentalFoundationApi' features of Jetpack Compose. The 'remember' function is used inside this Composable to construct a list of picture URLs, ensuring that the list is only computed once. The function "rememberPagerState" is utilized to establish a state for controlling the paging of images.

A "HorizontalPager" in the "Scaffold" enables horizontal swipes through a collection of images. The number of photos in the list is used as the 'pageCount' argument of the 'HorizontalPager', and the previously produced 'pagerState' is used as the 'state' parameter. The content for each page will is not there, and we will describe that in the next step.


@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
@Composable
fun ImageScreen() {

    val images = remember {
        mutableListOf(
            "https://www.gstatic.com/webp/gallery/1.webp",
            "https://www.gstatic.com/webp/gallery/2.webp",
            "https://www.gstatic.com/webp/gallery/3.webp",
            "https://www.gstatic.com/webp/gallery/4.webp",
            "https://www.gstatic.com/webp/gallery/5.webp",
        )
    }
    val pagerState = rememberPagerState()

    Scaffold(modifier = Modifier.padding(vertical = 48.dp)) {
        HorizontalPager(
            pageCount = images.size,
            state = pagerState,
            modifier = Modifier.padding(it)
        ) { index ->

                           //content for each page

        }
    }
}

Step 3. Define HorizontalPager

Above, we have seen how we defined the term "HorizontalPager." Let's now examine the "HorizontalPager" inside. This is used to generate a list of photos that pages through. A scaling animation effect is achieved for each image by using a 'AnimateFloatAsState' to calculate the image size based on the pager's current state. Additionally, a 'LaunchedEffect' is utilized to alter the 'ColorMatrix' dependent on the offset of the pager, changing the opacity of the image. An engaging and visually appealing image browsing experience is enhanced by the use of the 'AsyncImage' composable, which loads images asynchronously and applies animations, content scaling, rounded corner clipping, and color filtering using the modified 'ColorMatrix'. You can customize it definitely to suit your needs.

    //existing code 

    val colorMatrix = remember {
        ColorMatrix()
    }
    Scaffold(modifier = Modifier.padding(vertical = 48.dp)) {
        HorizontalPager(
            pageCount = images.size,
            state = pagerState,
            modifier = Modifier.padding(it)
        ) { index ->

            val pageOffset = (pagerState.currentPage - index) + pagerState.currentPageOffsetFraction
            val imageSize = animateFloatAsState(
                targetValue = if (pageOffset != 0.0f) 0.75f else 1f,
                animationSpec = tween(
                    durationMillis = 300
                ), label = ""
            ).value
            LaunchedEffect(key1 = imageSize) {
                if (pageOffset != 0.0f)
                    colorMatrix.setToScale(1f,1f,1f,0.9f)
                else
                    colorMatrix.setToScale(1f,1f,1f,1f,)
            }
            AsyncImage(
                model = ImageRequest.Builder(LocalContext.current).data(images[index]).build(),
                contentDescription = "Image",
                contentScale = ContentScale.Crop,
                modifier = Modifier
                    .fillMaxSize()
                    .padding(16.dp)
                    .clip(RoundedCornerShape(16.dp))
                    .graphicsLayer {
                        scaleX = imageSize
                        scaleY = imageSize
                    },
                colorFilter = ColorFilter.colorMatrix(colorMatrix)
            )
        }
    }

 You can download the attached project in this article. Let's check out the output.

Output

Conclusion

In this article, we have seen how to build some complicated animation in a simple way. Developers can easily design beautiful image transitions with animations thanks to Jetpack Compose. You may improve your Android app's visual appearance and interactivity by integrating animations and transitions. It will improve the user experience.

To give your app a distinctive and appealing feel, try out several animation styles, such as scale, fade, and other animations. The options are endless when it comes to making interesting picture transitions with Jetpack Compose's simple APIs. Hope this has been a helpful guide for you; it will be helpful for me if you write your genuine comment about this article. Thank you!


Similar Articles