The Modern Image Loading Library for Jetpack Compose
A powerful, flexible, and developer-friendly image loading solution built on top of Coil, designed specifically for Jetpack Compose applications.
Features β’ Installation β’ Quick Start β’ Documentation β’ Examples β’ Contributing
- β Minimum Shimmer Duration - Control how long the shimmer effect displays
- β Double-Tap to Zoom - Smooth zoom in/out with double-tap gesture
- β Animated Zoom Transitions - Buttery smooth zoom animations
- β Improved Error Handling - Better error states with icons
- β Enhanced Shimmer Effect - Diagonal animated shimmer
- β Better Shape Clipping - Proper shape handling for all states
- β Fullscreen Viewer Demo - Complete example with zoom support
- π Simple API - Single composable function for all image loading needs
- π¨ Shape Support - Built-in support for rounded corners, circles, and custom shapes
- β‘ Smart Loading States - Automatic shimmer placeholders and error handling
- π Zoom & Pan - Pinch-to-zoom, double-tap zoom, and smooth panning
- π Customizable UI - Custom placeholders and error composables
- π Crossfade Animation - Smooth transitions when images load
- β±οΈ Controlled Shimmer - Set minimum shimmer display time for better UX
- π¦ Powered by Coil 2.6 - Efficient caching and loading
- π― Content Scale Options - Crop, Fit, FillBounds, and more
- πΌοΈ Multiple Sources - URLs, files, and drawable resources (planned)
- βΏ Accessibility - Full content description support
- π¬ Compose-First - Built for modern Android development
Add JitPack to your settings.gradle.kts (root level):
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
}Add AsyncPic to your app module's build.gradle.kts:
dependencies {
implementation("com.github.PatilParas05:AsyncPic:2.0.0")
}Sync your project with Gradle files and you're ready to go! π
The simplest way to load an image:
AsyncPic(
url = "https://example.com/image.jpg",
modifier = Modifier.size(200.dp)
)AsyncPic(
url = "https://example.com/profile.jpg",
modifier = Modifier.size(100.dp),
shape = RoundedCornerShape(16.dp),
contentDescription = "Profile Picture"
)AsyncPic(
url = "https://example.com/avatar.jpg",
modifier = Modifier.size(80.dp),
shape = CircleShape,
contentDescription = "User Avatar"
)AsyncPic(
url = "https://example.com/photo.jpg",
modifier = Modifier.fillMaxSize(),
zoomable = true,
contentScale = ContentScale.Fit,
contentDescription = "Zoomable Photo"
)@Composable
fun AsyncPic(
url: String?,
modifier: Modifier = Modifier,
contentDescription: String? = null,
shape: Shape = RectangleShape,
placeholder: @Composable () -> Unit = { DefaultShimmer() },
error: @Composable () -> Unit = { DefaultError() },
zoomable: Boolean = false,
minShimmerTime: Long = 1000,
contentScale: ContentScale = ContentScale.Crop
)| Parameter | Type | Default | Description |
|---|---|---|---|
url |
String? |
Required | Image URL to load |
modifier |
Modifier |
Modifier |
Compose modifier for styling |
contentDescription |
String? |
null |
Accessibility description |
shape |
Shape |
RectangleShape |
Clip shape (RoundedCornerShape, CircleShape, etc.) |
placeholder |
@Composable () -> Unit |
DefaultShimmer() |
Custom loading placeholder |
error |
@Composable () -> Unit |
DefaultError() |
Custom error state UI |
zoomable |
Boolean |
false |
Enable pinch-to-zoom and double-tap |
minShimmerTime |
Long |
1000 |
Minimum shimmer display duration (ms) |
contentScale |
ContentScale |
ContentScale.Crop |
How to scale the image |
ContentScale.Crop- Scale to fill, cropping if necessary (default)ContentScale.Fit- Scale to fit entirely within boundsContentScale.FillBounds- Stretch to fill boundsContentScale.Inside- No scaling if image is smallerContentScale.FillWidth- Scale to match widthContentScale.FillHeight- Scale to match height
AsyncPic includes powerful zoom functionality:
- Pinch to Zoom: Scale from 1x to 4x
- Double-Tap: Toggle between normal and 3x zoom
- Pan: Move around when zoomed in
- Smooth Animations: 300ms animated transitions
- Auto-Reset: Returns to normal when scaled below 1x
AsyncPic(
url = imageUrl,
modifier = Modifier.fillMaxSize(),
zoomable = true,
contentScale = ContentScale.Fit
)Note: When
zoomable = true, the shape clipping is removed from the image itself to allow zoom to extend beyond bounds. The placeholder and error states still respect the shape.
AsyncPic is built on a modern Android architecture:
βββββββββββββββββββββββββββββββββββββββββββ
β Your Compose UI β
β β
β AsyncPic(url = "...") β
βββββββββββββββββββ¬ββββββββββββββββββββββββ
β
βββββββββββββββββββΌββββββββββββββββββββββββ
β AsyncPic Component β
β β’ State Management (Loading/Success) β
β β’ Shape Clipping β
β β’ Zoom Gesture Handling β
β β’ Minimum Shimmer Duration β
βββββββββββββββββββ¬ββββββββββββββββββββββββ
β
βββββββββββββββββββΌββββββββββββββββββββββββ
β Coil SubcomposeAsyncImage β
β β’ Image Loading β
β β’ Caching (Memory + Disk) β
β β’ Crossfade Animation β
β β’ Request Management β
βββββββββββββββββββββββββββββββββββββββββββ
- Min SDK: 26 (Android 8.0 Oreo)
- Target SDK: 36 (Android 15)
- Kotlin: 2.1+
- Compose: 1.7+
- Coil: 2.6.0
The repository includes a comprehensive demo app showcasing:
- Basic image loading
- Rounded corners and shapes
- Loading states with extended shimmer
- Error handling
- Fullscreen viewer with zoom
- Image grids
- Interactive UI
git clone https://github.com/PatilParas05/AsyncPic.git
cd AsyncPic
./gradlew :app:installDebugContributions are welcome! Here's how you can help:
- Report Bugs - Open an issue with details and reproduction steps
- Suggest Features - Share your ideas for improvements
- Submit PRs - Fix bugs or add features
- Improve Docs - Help make documentation better
- Share Feedback - Let us know how you're using AsyncPic
v1.x:
AsyncImageLoader(
data = ImageRequestData(
url = imageUrl,
transform = ImageTransformation.RoundedCorners(16.dp)
)
)v2.0:
AsyncPic(
url = imageUrl,
shape = RoundedCornerShape(16.dp)
)| Feature | v1.x | v2.0 |
|---|---|---|
| Main function | AsyncImageLoader |
AsyncPic |
| Configuration | ImageRequestData class |
Direct parameters |
| Transformations | ImageTransformation enum |
Compose Shape |
| Shimmer control | Not available | minShimmerTime parameter |
| Double-tap zoom | Not available | Built-in support |
AsyncPic is built for performance:
- β Memory Efficient - Coil's memory caching
- β Disk Caching - Automatic persistent cache
- β Request Deduplication - Multiple requests for same URL merged
- β Bitmap Pooling - Reuses bitmap memory
- β Lazy Loading - Only loads when visible
- β Cancellation - Automatic request cancellation
-
Check internet permission in
AndroidManifest.xml:<uses-permission android:name="android.permission.INTERNET"/>
-
Verify URL is accessible:
- Open URL in browser
- Check for HTTPS issues
- Verify network connection
-
Check Coil logs in Logcat:
Filter: coil
- Ensure
zoomable = trueis set - Use
ContentScale.Fitfor best zoom experience - Check that parent container allows gestures
- Reduce
minShimmerTimeparameter - Default is 1000ms (1 second)
- Set to
0Lto disable minimum duration
MIT License
Copyright (c) 2024 Paras Patil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
- Coil - The amazing image loading library powering AsyncPic
- Jetpack Compose - Modern Android UI toolkit
- Unsplash - Sample images in demo app
- Material Icons - Icons used in examples
If AsyncPic helped you build something awesome, please:
- β Star this repository
- π¦ Share on Twitter
- π Write a blog post
- π¬ Spread the word
Have a feature request? Open an issue with the label enhancement.
Made with β€οΈ for the Android Compose Community
