前言
做应用提高用户体验是很关键的,对于用户体验来说有一件事是不能回避的,就是页面切换的过渡动画。因为后一个页面可能会加载数据,所以切换时后一个页面是空白的导致用户体验比较差。那么如果下一个页面数据加载可能很快,为了提供流畅的顶级导航过渡,可不可以等待第二个屏幕加载数据,然后再启动动画?
Android中的Fragment就提供了这种功能,通过它可以推迟fragment的载入,这样在界面通过动画过渡到第二个屏幕之前,第二个屏幕上的界面元素(通常是从网络获取的图片)已做好显示准备。这便是:postponeEnterTransition()
和startPostponedEnterTransition()
postponeEnterTransition
这个函数会延迟Fragment的导航过渡直到执行了startPostponedEnterTransition()
或executePendingTransactions()
。所以这个函数给Fragment提供了推迟动画直到数据都加载完成的能力。
需要注意的是,这个函数必须在fragment被添加到FragmentTransaction之前执行,或者在onCreate
, onAttach
, onCreateView
这几个生命周期中执行。而已这个函数之后必须执行startPostponedEnterTransition()
或executePendingTransactions
,否则fragment的导航过渡无法完成。
startPostponedEnterTransition
这个函数与postponeEnterTransition()
搭配使用,可以启动被postponeEnterTransition推迟的导航过渡。而且在postponeEnterTransition()
之后必须执行startPostponedEnterTransition()
或executePendingTransactions
,否则fragment的导航过渡无法完成。
这里注意executePendingTransactions()
也有同样的效果,如果这次延迟时间被executePendingTransactions()
干扰了,那么在startPostponedEnterTransition()
执行之前,过渡动画可能没执行也可能已经执行了。所以在使用过程中要特别注意是否有executePendingTransactions()
干预。
executePendingTransactions
既然提到了executePendingTransactions()
,那么也一起说一下这个函数。
当一个fragment添加到FragmentTransaction并commit之后,导航过渡其实并不是立刻执行,而是被安排异步的在主线程中执行(这点我想大家都比较了解了,所以FragmentTransaction也提供了commitNow()
函数)。而executePendingTransactions()
可以让这个动作立刻执行,所以它也会强制因postponeEnterTransition()
而推迟的导航过渡直接启动。
所以在使用postponeEnterTransition()
的时候,一定要注意executePendingTransactions()
的存在。
总结
使用起来还是比较简单的,但是注意不能滥用。比如fragment页面数据很多,需要的网络请求可能时间较长,如果你在请求结束后再执行startPostponedEnterTransition()
,那么用户点击之后会在当前页面停顿很久才导航到新页面,这样用户体验会很差。所以它适合那些加载较快的操作,比如网络图片,这样在导航过渡时,尤其是有共享元素的时候,下一个页面的对应内容已经准备好了,动画效果会更好。