基于 Compose Multiplatform 与 Kotlin Multiplatform 的容器共享(SharedContainer)、页面导航(Navigation)以及全局浮窗(FloatingWindow)库。
复刻系统 Launcher 动画,支持背景模糊、镜面缩放,1像素填充、二次贝赛尔插值、屏幕圆角贴合、预测式返回、并行打断动画等特性;相比于目前官方文档推荐的方案(Navigation2+SharedElements),可以显著简化 Compose 应用在此方面的开发流程,提高可定制性,且拥有更流畅、精美的交互视觉体验。
支持平台:Wasm(JS)、Desktop(JVM)、iOS、Android

./gradlew :app:wasmJsBrowserDevelopmentRun
./gradlew :app:wasmJsBrowserProductRun
./gradlew :app:jsBrowserDevelopmentRun
./gradlew :app:jsBrowserProductRun
./gradlew :app:run
./gradlew :app:wasmJsBrowserDistribution
./gradlew :appjsBrowserDistribution
./gradlew :app:packageDistributionForCurrentOS
⚠️ 本库目前仍处于开发阶段,目前已在聚在工大项目中实际使用,可以体验实际交互效果,看一下里面代码使用方式,再慎重考虑是否接入本库,如有 Bug 及时提。
在settings.gradle添加
Groovy使用
maven {
url 'https://jitpack.io'
}Kotlin使用
maven {
url = uri("https://jitpack.io")
}添加依赖,版本以 Release 的 Tag 为准
Android 项目:
implementation("com.github.Chiu-xaH.SharedNav:navigation-android:<version>")KMP 项目,在commonMain里添加:
implementation("com.github.Chiu-xaH.SharedNav:navigation:<version>")KMP 项目,按平台添加:
implementation("com.github.Chiu-xaH.SharedNav:navigation-android:<version>")
implementation("com.github.Chiu-xaH.SharedNav:navigation-jvm:<version>")
implementation("com.github.Chiu-xaH.SharedNav:navigation-ios:<version>")
implementation("com.github.Chiu-xaH.SharedNav:navigation-wasmJs:<version>")这里以 Android 为例,其余平台类似。
./gradlew assembleRelease在各自模块的build/outputs/aar目录找到 aar 产物,拷贝到要引入的应用模块下的libs文件夹中
def tag = "release"
implementation(files("libs/common-${tag}.aar"))
implementation(files("libs/navigation-${tag}.aar"))
implementation(files("libs/shared-container-${tag}.aar"))
implementation(files("libs/floating-window-${tag}.aar"))
implementation(files("libs/shader-${tag}.aar"))每个页面对应一个 Destination 对象,继承抽象类并实现 key 与 Content():
object HomeDestination : Destination() {
override val key = "home" // 全局唯一,同时用作容器共享的匹配 Key
@Composable
override fun Content() {
HomeScreen()
}
}在 Activity 或顶层 Composable 中启动导航:
val navController = rememberNavController(startDestination = HomeDestination)
SharedNavHost(
navController = navController
)在任意 Composable 中通过 LocalNavController 或 LocalNavControllerSafely 获取控制器:
提示:如果无法保证 Composable 函数一定在
SharedNavHost下调用,请使用LocalNavControllerSafely,它返回可空对象;LocalNavController获取不到控制器时会直接抛出异常导致 Crash。
@Composable
fun HomeScreen() {
val navController = LocalNavController.current
Button(
onClick = { navController.push(DetailDestination) }
) {
Text("进入详情")
}
Button(
onClick = { navController.pop() },
) {
Text("返回")
}
}用 SharedContainer 包裹触发跳转的组件,key 与目标 Destination.key 保持一致,即可获得容器共享的展开/收起动画。
写法 1:
@Composable
fun HomeScreen() {
val navController = LocalNavController.current
val dest = remember(id) { DetailDestination(id) }
SharedContainer(
key = dest.key,
shape = MaterialTheme.shapes.medium,
) {
Card(
shape = NoneRoundShape,
onClick = { navController.push(dest) }
) {
/* 内容 */
}
}
}写法 2:Modifier 扩展
@Composable
fun HomeScreen() {
val navController = LocalNavController.current
val dest = remember(id) { DetailDestination(id) }
Card(
modifier = Modifier.sharedContainer(
key = dest.key,
shape = MaterialTheme.shapes.medium
),
shape = NoneRoundShape,
onClick = { navController.push(dest) }
) {
/* 内容 */
}
}注意:
SharedContainer内层组件的shape必须设置为无圆角,圆角统一由外层SharedContainer管理,否则在提取 1 像素时会缺失边角。
已写好,待发布