A modern Android library for creating Instagram/Snapchat-style stories using Jetpack Compose. This library provides a customizable and easy-to-use component for displaying sequential content with automatic progression and user interaction controls.
- ๐ฌ Automatic Story Progression: Stories automatically advance with customizable timing
- ๐จ Multiple Background Types: Support for drawable resources and URLs
- ๐ฎ Interactive Controls: Tap to navigate, pause/play functionality
- ๐ฑ Customizable UI: Configurable progress bars, colors, and animations
- ๐ฏ Compose Integration: Built with Jetpack Compose for modern Android development
- ๐ฆ Lightweight: Minimal dependencies and optimized performance
Add the dependency to your app's build.gradle.kts:
dependencies {
implementation("com.github.rustamsafarovrs:stories:1.1.0")
}@Composable
fun MyStories() {
val storiesModel = StoriesModel(
slides = listOf(
StoriesModel.Slide(drawableBackground(R.drawable.image1)),
StoriesModel.Slide(urlBackground("https://example.com/image.jpg")),
StoriesModel.Slide(drawableBackground(R.drawable.image2))
)
)
Stories(
model = storiesModel,
didFinish = {
// Handle story completion
}
)
}@Composable
fun StoriesWithOverlay() {
val controller = remember { StoriesController() }
val storiesModel = StoriesModel(
slides = listOf(
StoriesModel.Slide(
background = drawableBackground(R.drawable.image1),
overlay = {
Text(
"Custom overlay content",
color = Color.White,
modifier = Modifier.padding(16.dp)
)
}
)
)
)
Stories(
model = storiesModel,
controller = controller,
didFinish = { /* Handle completion */ }
)
}The main composable for displaying stories.
@Composable
fun Stories(
model: StoriesModel,
controller: StoriesController = remember { StoriesController() },
didFinish: () -> Unit = {}
)Parameters:
model: The stories data model containing slides and configurationcontroller: Optional controller for programmatic navigationdidFinish: Callback invoked when all stories are completed
Data class representing the stories content and configuration.
data class StoriesModel(
val slides: List<Slide>,
val config: StoriesDefaults = StoriesDefaults()
)Individual story slide with background and optional overlay.
data class Slide(
val background: Background,
val overlay: @Composable () -> Unit = {}
)StoriesModel.Slide(drawableBackground(R.drawable.my_image))StoriesModel.Slide(urlBackground("https://example.com/image.jpg"))Control story playback programmatically.
val controller = remember { StoriesController() }
// Navigate to next slide
controller.goNext()
// Navigate to previous slide
controller.goPrevious()
// Pause story progression
controller.doPause()
// Resume story progression
controller.doPlay()Configuration options for story behavior and appearance.
data class StoriesDefaults(
val slideDurationMs: Long = 3_000L, // Duration per slide
val progressSpaceBetween: Dp = 8.dp, // Space between progress bars
val progressBackgroundColor: Color = Color.LightGray, // Progress bar background
val progressColor: Color = Color.Blue, // Progress bar color
val progressHeight: Dp = 4.dp, // Progress bar height
val progressRadius: Dp = 2.dp, // Progress bar corner radius
val clickToChangeEnabled: Boolean = true, // Enable tap navigation
val clickToPauseEnabled: Boolean = true, // Enable tap to pause
val shimmerBackgroundColor: Color = Color.White, // Shimmer effect background
val shimmerHighlightColor: Color = Color.LightGray, // Shimmer effect highlight
val shimmerDuration: Int = 1000 // Shimmer animation duration
)- Left side tap: Go to previous slide
- Right side tap: Go to next slide
- Tap and hold: Pause story progression
- Tap and hold anywhere to pause
- Release to resume playback
- Tap left/right edges to navigate
val customConfig = StoriesDefaults(
slideDurationMs = 5_000L,
progressColor = Color.Red,
progressHeight = 6.dp,
clickToPauseEnabled = false
)
val storiesModel = StoriesModel(
slides = slides,
config = customConfig
)@Composable
fun CustomSlideOverlay(controller: StoriesController) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
Text(
"Story Title",
color = Color.White,
style = MaterialTheme.typography.headlineMedium
)
Spacer(modifier = Modifier.weight(1f))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
Button(onClick = { controller.goPrevious() }) {
Text("Previous")
}
Button(onClick = { controller.goNext() }) {
Text("Next")
}
}
}
}- Minimum SDK: 24 (Android 7.0)
- Target SDK: 35
- Kotlin: 2.1.21+
- Jetpack Compose: 2025.06.00+
- Java: 17+
The library uses the following dependencies:
- Jetpack Compose UI
- Jetpack Compose Material3
- Glide Compose (for image loading)
- Landscapist Glide (for image display with shimmer effects)
The project includes a sample app demonstrating various usage patterns. Run the sample to see the library in action.
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.