Skip to content

Implemented shared element transitions with Compose Animation, type-safe navigation, and Coil for fetching image from internet.

Notifications You must be signed in to change notification settings

js-bhavyansh/Shared_Element_Transition

Repository files navigation

Shared Element Transition with Jetpack Compose

This project demonstrates how to implement shared element transitions using Jetpack Compose Animation and type-safe navigation with serialization. It also utilizes Coil to fetch images from the internet through URLs.

Features

  • Shared Element Transition: Smooth and customizable transitions between composable elements.
  • Type-safe Navigation: Robust navigation between screens using Kotlin serialization.
  • Image Loading with Coil: Efficient image loading from URLs.

Screenshots

First Screenshot

Installation

  1. Clone the repository:

    git clone https://github.com/Bhavyansh03-tech/Shared_Element_Transition.git
  2. Open the project in Android Studio.

  3. Sync the project with Gradle files.

Usage

Dependencies

Add the following dependencies in your libs.versions.toml file:

[versions] # COIL COMPOSE :-> coil = "2.6.0" # ANIMATION :-> animation = "1.7.0-beta05" foundation = "1.7.0-beta05" # NAVIGATION :-> navigationCompose = "2.8.0-beta05" kotlinxSerializationJson = "1.7.1" [libraries] # ANIMATION :-> androidx-animation = { module = "androidx.compose.animation:animation", version.ref = "animation" } androidx-animation-core = { module = "androidx.compose.animation:animation-core", version.ref = "animation" } androidx-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "foundation" } # NAVIGATION :-> androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" } # COIL COMPOSE :-> coil = { module = "io.coil-kt:coil-compose", version.ref = "coil" } [plugins] # COMPOSE COMPILER :-> compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } # NAVIGATION kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }

Kotlin Serialization

To use Kotlin serialization, first, annotate your data class with @Serializable:

import kotlinx.serialization.Serializable @Serializable object Home @Serializable data class Detail( val imageIdArg: Int = 1 )

Then, pass the serialized data through the navigation:

composable<Detail> { val args = it.toRoute<Detail>() DetailScreen( animatedVisibilityScope = this@composable, imageId = args.imageIdArg, // Passing Image Id As Argument. onClick = { navController.popBackStack() } // Going back to previous activity by removing it from back stack. ) }

Shared Element Transition

Shared element transitions are implemented for both images and text. Below is an example of how to achieve this:

@OptIn(ExperimentalSharedTransitionApi::class) @Composable fun SharedTransitionScope.DetailScreen( animatedVisibilityScope: AnimatedVisibilityScope, imageId: Int, onClick: () -> Unit ) { Column(modifier = Modifier.fillMaxSize()) { AsyncImage( modifier = Modifier .sharedElement( state = rememberSharedContentState(key = "image-${imageId}"), animatedVisibilityScope = animatedVisibilityScope ) .fillMaxWidth() .height(350.dp) .clickable { onClick() }, model = imageList[imageId - 1].photo, contentDescription = null, contentScale = ContentScale.Crop ) Box( modifier = Modifier .fillMaxSize() .padding(all = 12.dp) ) { Text( modifier = Modifier .sharedBounds( sharedContentState = rememberSharedContentState(key = "text-${imageId}"), animatedVisibilityScope = animatedVisibilityScope ), text = imageList[imageId - 1].title, fontSize = MaterialTheme.typography.titleLarge.fontSize, fontWeight = FontWeight.Medium ) } } }

Image Transition

AsyncImage( modifier = Modifier .sharedElement( state = rememberSharedContentState(key = "image-${imageId}"), animatedVisibilityScope = animatedVisibilityScope ) .fillMaxWidth() .height(350.dp) .clickable { onClick() }, model = imageList[imageId - 1].photo, contentDescription = null, contentScale = ContentScale.Crop )

Text Transition

Text( modifier = Modifier .sharedBounds( sharedContentState = rememberSharedContentState(key = "text-${imageId}"), animatedVisibilityScope = animatedVisibilityScope ), text = imageList[imageId - 1].title, fontSize = MaterialTheme.typography.titleLarge.fontSize, fontWeight = FontWeight.Medium )

Contributing

Contributions are welcome! Please fork the repository and submit a pull request for any improvements or bug fixes.

  1. Fork the repository.
  2. Create your feature branch (git checkout -b feature/your-feature).
  3. Commit your changes (git commit -am 'Add some feature').
  4. Push to the branch (git push origin feature/your-feature).
  5. Create a new Pull Request.

Contact

For questions or feedback, please contact @Bhavyansh03-tech.


About

Implemented shared element transitions with Compose Animation, type-safe navigation, and Coil for fetching image from internet.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages