Compose 页面切换动画

简介: Compose 页面切换动画

Compose 页面切换动画


0bff4d719b88466ea173d517805f01d6.png

前因后果

在之前我写了 Compose 版本的玩安卓,当然也有 MVVM 版本的,只是不同分支而已,这是 Github地址:https://github.com/zhujiang521/PlayAndroid

但之前一直存在着一个问题,就是页面切换的时候没有动画,也不能说没有动画,可以通过 Crossfade 来实现两个页面之间的淡入淡出,但这就够了吗?完全不够啊!咱们的产品和UI第一个不答应,只是淡入淡出是绝对不行的!

开始尝试

其实 Compose 中的 Navigation 就是之前 Jetpack 中的 Navigation 改的,所以之前的 api 还是存在的,

然后用上试试呗!

navController.navigate(route) {
    anim {
        enter = R.anim.in_from_right
        exit = R.anim.out_to_left
        popEnter = R.anim.in_from_right
        popExit = R.anim.out_to_left
    }
}

然后就有了上面的代码进行尝试,其实写的时候也想过不行,因为在 Compose 中动画有自己的一套实现方式,并不是像之前那样放在 anim 文件夹下的 xml 文件,但还是抱着试一试的态度,最后发现。。。果然不行。。。

于是开始一顿乱找,后来发现在官方文档中已经写明了:

注意:anim 块不能与 Navigation Compose 一起使用。系统会在此功能请求中跟踪 Navigation Compose 中的转换动画。

然后就没有然后了,就开始等。。。。这一等就是好久。(其实这篇文章是之前写的,但一直没发)

终于在前段时间,这个问题有了眉目,Google 并没有将这个功能放到 Navigation 库中,而是重新创建了一个库:navigation-animation,使用的时候同时引入即可进行使用。

开始撸码

首先需要做的肯定是添加依赖:

现在应用级的 build.gradle 中添加:

repositories {
    mavenCentral()
}

然后在 Module 级的 build.gradle 中添加:

// Navigation 动画
implementation "com.google.accompanist:accompanist-navigation-animation:$accompanist_version"

接下来需要做的是迁移之前写的 Navigation 的代码,先来看看之前的写法吧:

@ExperimentalPagingApi
@Composable
fun NavGraph(
    startDestination: String = MainDestinations.HOME_PAGE_ROUTE
) {
    val navController = rememberNavController()
    val actions = remember(navController) { MainActions(navController) }
    NavHost(
        navController = navController,
        startDestination = startDestination
    ) {
        composable(MainDestinations.HOME_PAGE_ROUTE) {
            Home(actions)
        }
    }
}

需要做的迁移有:

  • 替换rememberNavController()为rememberAnimatedNavController()
  • 替换NavHost为AnimatedNavHost
  • 替换import androidx.navigation.compose.navigation为import com.google.accompanist.navigation.animation.navigation
  • 替换import androidx.navigation.compose.composable为import com.google.accompanist.navigation.animation.composable

那就来吧:

@OptIn(ExperimentalAnimationApi::class, ExperimentalPagerApi::class)
@Composable
fun NavGraph(
    startDestination: String = PlayDestinations.HOME_PAGE_ROUTE,
) {
    val navController = rememberAnimatedNavController()
    val actions = remember(navController) { PlayActions(navController) }
    AnimatedNavHost(
        navController = navController,
        startDestination = startDestination
    ) {
        setComposable(PlayDestinations.HOME_PAGE_ROUTE) {
            WeatherViewPager(
                toCityList = actions.toCityList,
                toWeatherList = actions.toWeatherList
            )
        }
    }
}

下面就来看看如何使用这个库为页面之间切换添加动画吧:

@ExperimentalAnimationApi
public fun NavGraphBuilder.navigation(
    startDestination: String,
    route: String,
    enterTransition: (AnimatedContentScope<NavBackStackEntry>.() -> EnterTransition?)? = null,
    exitTransition: (AnimatedContentScope<NavBackStackEntry>.() -> ExitTransition?)? = null,
    popEnterTransition: (
        AnimatedContentScope<NavBackStackEntry>.() -> EnterTransition?
    )? = enterTransition,
    popExitTransition: (
        AnimatedContentScope<NavBackStackEntry>.() -> ExitTransition?
    )? = exitTransition,
    builder: NavGraphBuilder.() -> Unit
)

上面这段代码是 navigation-animation 库中的源码,可以看到除了之前 Navigation 库中的一些参数外还多了几个参数用来设置动画,来具体看看吧:

  • **enterTransition:**在此 NavGraph 中定义目的地的输入转换动画
  • **exitTransition:**在此 NavGraph 中为目的地定义退出转换动画
  • **popEnterTransition:**在此 NavGraph 中定义目的地的弹出输入转换动画
  • **popExitTransition:**在此 NavGraph 中为目的地定义弹出退出转换动画

再来看看具体使用吧:

composable(
    route = route,
    arguments = arguments,
    deepLinks = deepLinks,
    enterTransition = {
        expandVertically(animationSpec = tween(300))
    },
    exitTransition = {
        shrinkOut(animationSpec = tween(300))
    },
    popEnterTransition = {
        expandVertically(animationSpec = tween(300))
    },
    popExitTransition = {
        shrinkOut(animationSpec = tween(300))
    },
    content = content,
)

OK,这就可以了。大家可以多种组合动画尝试下,可以实现各种你想要的动画。

仓促的结尾

本篇文章到这里就差不多了,但如果大家没有使用过 Compose 或者对之前使用的 Navigation 并不熟悉的话可以先去看看我之前的文章



目录
相关文章
Flutter ListView懒加载(滑动不加载,停止滑动加载)
前言:为了更好的减小网络的带宽,使得列表更加流畅,我们需要了解懒加载,也称延迟加载。关于上一章的登录界面,各位属实难为我了,我也在求ui小姐姐,各位点点赞给我点动力吧~
|
4月前
|
前端开发 数据可视化 图形学
Framer快速搭建滚动动画网站(无代码)
Framer快速搭建滚动动画网站(无代码)
79 0
|
5月前
|
JavaScript
vue 动画 —— 滚动动画
vue 动画 —— 滚动动画
74 0
|
5月前
Flutter-加载中动画
Flutter-加载中动画
47 0
|
6月前
|
API 容器
Flutter 自定义实现时间轴、侧边进度条
Flutter 自定义实现时间轴、侧边进度条
202 0
|
7月前
|
JavaScript 前端开发
jQuery 第五章(效果,滑动,动画,停止动画)
jQuery 第五章(效果,滑动,动画,停止动画)
89 0
|
移动开发 前端开发 JavaScript
【前端动画】实现动画的6种方式
【前端动画】实现动画的6种方式
1248 0
|
JavaScript 前端开发
【jQuery动画】停止动画、淡入淡出、自定义动画
动画队列中所有动画都是按照顺序执行的,默认只有当前的一个动画执行完毕,才会执行后面的动画。为此,jQuery提供了stop()方法用于停止动画效果。通过此方法,可以让动画队列后面的动画提前执行。
|
JavaScript
vue vue3 实现滚动进度条,斑马纹进度条
vue vue3 实现滚动进度条,斑马纹进度条
vue vue3 实现滚动进度条,斑马纹进度条
|
JSON 缓存 Android开发
玩转 Compose 中的 Lottie 动画
玩转 Compose 中的 Lottie 动画
424 0