
Security News
AGENTS.md Gains Traction as an Open Format for AI Coding Agents
AGENTS.md is a fast-growing open format giving AI coding agents a shared, predictable way to understand project setup, style, and workflows.
am.highapps.parallaxtoolbar:compose-parallax-toolbar-kmp
Advanced tools
ComposeParallaxToolbar is a Jetpack Compose Multiplatform library that provides a customizable collapsing toolbar/app bar with a parallax background effect for both iOS and Android.
A fully customizable Material 3 parallax toolbar layout built with Compose Multiplatform. This cross-platform library provides a modern, material design parallax effect for app bars that animate smoothly as users scroll through content, working seamlessly on Android, iOS.
For Compose Multiplatform projects, add the dependency to your shared module's build.gradle.kts
:
kotlin {
sourceSets {
commonMain {
dependencies {
implementation("am.highapps.parallaxtoolbar:compose-parallax-toolbar-kmp:1.3.0")
}
}
}
}
This will make the library available in all your platform-specific source sets (androidMain, iosMain, etc.).
Add the dependency to your module's build.gradle.kts file:
dependencies {
implementation("am.highapps.parallaxtoolbar:compose-parallax-toolbar-kmp:1.3.0")
}
dependencies {
implementation 'am.highapps.parallaxtoolbar:compose-parallax-toolbar-kmp:1.3.0'
}
For direct integration:
Download the project from GitHub repository
After downloading, run the following command to build the iOS framework:
./gradlew buildIosFramework
xcodebuild -create-xcframework \
-framework compose-parallax-toolbar-kmp/build/bin/iosArm64/releaseFramework/compose_parallax_toolbar_kmp.framework \
-framework compose-parallax-toolbar-kmp/build/bin/iosSimulatorArm64/releaseFramework/compose_parallax_toolbar_kmp.framework \
-output compose-parallax-toolbar-kmp.xcframework
Integrate XCFramework with Xcode:
compose-parallax-toolbar-kmp.xcframework
and add itImport in your Swift files:
import compose_parallax_toolbar_kmp
Here's a simple example of how to implement the parallax toolbar in your Compose code:
import am.highapps.parallaxtoolbar.ComposeParallaxToolbarLayout
import am.highapps.parallaxtoolbar.ParallaxContent
@Composable
fun MyScreen() {
ComposeParallaxToolbarLayout(
titleContent = { isCollapsed ->
Text(
text = "My App",
style = if (isCollapsed)
MaterialTheme.typography.titleMedium
else
MaterialTheme.typography.headlineMedium
)
},
headerContent = {
// Your header image or content
Image(
painter = painterResource(id = R.drawable.header),
contentDescription = null,
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize()
)
},
content = ParallaxContent.Regular { isCollapsed ->
// Your main content
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
repeat(10) { index ->
Card(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
) {
Text(
text = "Item ${index + 1}",
modifier = Modifier.padding(16.dp)
)
}
}
}
}
)
}
For Android, you can use the component directly in your Compose UI:
import am.highapps.parallaxtoolbar.ParallaxContent
@Composable
fun AndroidScreen() {
// Use Material Theme from your Android app
MaterialTheme {
ComposeParallaxToolbarLayout(
titleContent = { isCollapsed ->
Text(
text = "Android App",
fontSize = if (isCollapsed) 18.sp else 24.sp,
fontWeight = FontWeight.Bold,
color = if (isCollapsed)
MaterialTheme.colorScheme.onSurface
else
Color.White
)
},
headerContent = {
Box(
modifier = Modifier
.background(MaterialTheme.colorScheme.primary)
.fillMaxSize()
)
},
content = ParallaxContent.Regular { isCollapsed ->
LazyColumn(
modifier = Modifier.fillMaxWidth()
) {
items(20) { index ->
ListItem(
headlineContent = { Text("Item $index") },
supportingContent = { Text("Supporting text") }
)
}
}
}
)
}
}
import UIKit
import compose_parallax_toolbar_kmp
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let composeVC = IosParallaxToolbarSampleKt.SimpleParallaxToolbarViewController()
addChild(composeVC)
view.addSubview(composeVC.view)
composeVC.view.frame = view.bounds
composeVC.didMove(toParent: self)
}
}
import SwiftUI
import compose_parallax_toolbar_kmp
struct ComposeToolbarView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
return IosParallaxToolbarSampleKt.SimpleParallaxToolbarViewController()
}
func updateUIViewController(_ uivc: UIViewController, context: Context) {}
}
struct ContentView: View {
var body: some View {
ComposeToolbarView()
.ignoresSafeArea(edges: .top) // Optional: makes the toolbar use full height
}
}
iOS Sample View Controllers:
SimpleParallaxToolbarViewController()
- Basic implementation with regular contentLazyParallaxToolbarViewController()
- LazyColumn content exampleLazyWithPaddingViewController()
- Custom padding configurationLazyWithSpacingViewController()
- Custom spacing and arrangementLazyWithScrollControlViewController()
- Custom scroll behaviorIOSSettingsStyleViewController()
- iOS Settings app style with grouped sectionsIOSPhotoGalleryViewController()
- iOS Photos app style with grid layoutAllSamplesViewController()
- Container with all samplesTo create custom implementations, you need to add your custom composable functions in the common code (specifically in the iOS part of the multiplatform module), then use them from your iOS application.
Step 1: Add your custom implementation in the common code (iOS part):
// Add this in src/iosMain/kotlin (common code - iOS part)
import am.highapps.parallaxtoolbar.ParallaxContent
fun MyCustomToolbarViewController() = ComposeUIViewController {
MaterialTheme {
ComposeParallaxToolbarLayout(
titleContent = { isCollapsed ->
Text(
text = "My Custom Title",
fontSize = if (isCollapsed) 18.sp else 24.sp,
fontWeight = FontWeight.Bold,
color = if (isCollapsed)
MaterialTheme.colorScheme.onSurface
else
Color.White
)
},
headerContent = {
Box(
modifier = Modifier
.background(
brush = Brush.verticalGradient(
colors = listOf(Color(0xFF4CAF50), Color(0xFF2E7D32))
)
)
.fillMaxSize()
)
},
content = ParallaxContent.Lazy(
content = { isCollapsed ->
items(50) { index ->
Card(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp)
) {
Text(
text = "Custom Item ${index + 1}",
modifier = Modifier.padding(16.dp)
)
}
}
},
config = ParallaxToolbarDefaults.lazyColumnConfig(
contentPadding = PaddingValues(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
),
lazyListState = rememberLazyListState()
)
)
}
}
Step 2: After adding your custom implementation, rebuild the framework:
./gradlew buildIosFramework
Step 3: Use it in your iOS application:
// In your iOS app
let customVC = IosParallaxToolbarSampleKt.MyCustomToolbarViewController()
Note: Custom implementations cannot be created directly in the iOS application code. They must be added to the common multiplatform code (iOS part) and then accessed from the iOS app.
For more details:
For more control, use the ParallaxToolbarDefaults
object to customize various aspects:
import am.highapps.parallaxtoolbar.ParallaxContent
import am.highapps.parallaxtoolbar.ParallaxToolbarDefaults
// Create customized configurations using factory methods
// NEW: Responsive header height with aspect ratio
val headerConfig = ParallaxToolbarDefaults.headerConfigWithAspectRatio(
aspectRatio = 16f/9f, // Responsive widescreen header
gradient = Brush.verticalGradient(
colors = listOf(
Color.Transparent,
Color(0x80000000),
Color(0xCC000000)
),
startY = 300f
)
)
val titleConfig = ParallaxToolbarDefaults.titleConfig(
paddingStart = 20.dp,
collapsedPaddingStart = 60.dp,
keepSubtitleAfterCollapse = true,
animateSubTitleHiding = true
)
val toolbarConfig = ParallaxToolbarDefaults.toolbarConfig(
initialColor = Color.Transparent,
targetColor = MaterialTheme.colorScheme.surface,
elevation = 2.dp,
animationSpec = tween(durationMillis = 400)
)
val bodyConfig = ParallaxToolbarDefaults.bodyConfig(
minBottomSpacerHeight = 32.dp
)
ComposeParallaxToolbarLayout(
// Required parameters
titleContent = { /* ... */ },
headerContent = { /* ... */ },
content = ParallaxContent.Regular { /* ... */ },
// Scaffold integration (important for bottom navigation)
contentPadding = paddingValues, // Pass from Scaffold for proper spacing
// Optional customizations
headerConfig = headerConfig,
toolbarConfig = toolbarConfig,
titleConfig = titleConfig,
bodyConfig = bodyConfig
)
For ParallaxContent.Lazy
, you can customize the LazyColumn behavior using LazyColumnConfig
:
import am.highapps.parallaxtoolbar.ParallaxContent
import am.highapps.parallaxtoolbar.ParallaxToolbarDefaults
// Create a custom LazyColumn configuration
val lazyConfig = ParallaxToolbarDefaults.lazyColumnConfig(
contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp),
verticalArrangement = Arrangement.spacedBy(12.dp),
horizontalAlignment = Alignment.CenterHorizontally,
userScrollEnabled = true,
flingBehavior = null, // Uses default
overscrollEffect = null // Uses default
)
// Example with external LazyListState control
val lazyListState = rememberLazyListState()
// You can programmatically control scrolling
LaunchedEffect(someCondition) {
lazyListState.animateScrollToItem(index = 10)
}
ComposeParallaxToolbarLayout(
titleContent = { isCollapsed ->
Text(
text = "Custom LazyList",
fontSize = if (isCollapsed) 18.sp else 24.sp,
fontWeight = FontWeight.Bold
)
},
headerContent = { /* ... */ },
// For Scaffold integration (merges with LazyColumn's own contentPadding)
contentPadding = paddingValues, // External padding (e.g., from Scaffold)
content = ParallaxContent.Lazy(
content = { isCollapsed ->
items(100) { index ->
Card(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp)
) {
Text(
text = "Item ${index + 1}",
modifier = Modifier.padding(16.dp)
)
}
}
},
config = lazyConfig, // Internal LazyColumn padding (16dp) + External padding = Total padding
lazyListState = lazyListState // Pass your controlled state
)
)
For detailed information on all components, parameters, and configuration options, see the API Documentation.
isCollapsed
parameterTopAppBar
ParallaxContent.Lazy
for large lists to ensure optimal performanceremember
and derivedStateOf
for scroll-based calculationsParallaxContent.Regular
for regular scrollable content, ParallaxContent.Lazy
for LazyColumn)HeaderHeight
sealed class:
HeaderHeight.Fixed
: Fixed height in Dp (previous default behavior)HeaderHeight.AspectRatio
: Responsive height based on screen width and aspect ratioHeaderHeight.Percentage
: Adaptive height as percentage of screen heightcontentPadding
parameter for seamless Scaffold integration
ParallaxContent.Lazy
with comprehensive LazyColumnConfig
customization
ParallaxToolbarDefaults.lazyColumnConfig()
for easy configurationParallaxContent
sealed class system for content types:
ParallaxContent.Regular
- Regular scrollable content using Column with vertical scrollParallaxContent.Lazy
- LazyColumn content for better performance with large listsComposeParallaxToolbarLayout
with single content: ParallaxContent
parameterContributions are welcome! Check out the Contributing Guidelines for more information.
This library was inspired by and based mainly on the excellent article Collapsing toolbar with parallax effect and curve motion in Jetpack Compose by Morad Azzouzi.
This project was created by Hayk Arustamyan.
⭐ If you find this library helpful, consider giving it a star on GitHub!
If this project helps you reduce time to develop, you can give me a cup of coffee :)
MIT License
Copyright (c) 2025 Hayk Arustamyan
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.
FAQs
Unknown package
We found that am.highapps.parallaxtoolbar:compose-parallax-toolbar-kmp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
AGENTS.md is a fast-growing open format giving AI coding agents a shared, predictable way to understand project setup, style, and workflows.
Security News
/Research
Malicious npm package impersonates Nodemailer and drains wallets by hijacking crypto transactions across multiple blockchains.
Security News
This episode explores the hard problem of reachability analysis, from static analysis limits to handling dynamic languages and massive dependency trees.