Android转场动画深度解析(2)

紧接着上一篇介绍了Scene和Transition的基本用法后,这篇开始介绍如何运用这些到转场动画中。从A页面到B页面,再从B页面返回到A页面,这就是一个完整的转场过程。而转场动画就是负责来优雅地协调处理好这个过程的。android

Content Transition

Content Transition就是最多见的转场动画了。为了方便你们理解,咱们先来上个图。bash

部分代码:

源Activity:

Slide slide=new Slide();
slide.setDuration(3000);
slide.setSlideEdge(Gravity.BOTTOM);
getWindow().setExitTransition(slide);

Explode explode = new Explode();
explode.setDuration(3000);
explode.setMode(Visibility.MODE_IN);
getWindow().setReenterTransition(explode);
复制代码

目标Activity:

Slide slideEnter=new Slide();
slideEnter.setDuration(1500);
slideEnter.setSlideEdge(Gravity.RIGHT);
getWindow().setEnterTransition(slideEnter);

Slide slide=new Slide();
slide.setDuration(1500);
slide.setSlideEdge(Gravity.RIGHT);
getWindow().setReturnTransition(slide);
复制代码

而后在A页面调用方法跳到B页面:ide

Intent intent = new Intent(this, BActivity.class);
ActivityOptionsCompat activityOptionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(this);
startActivity(intent, activityOptionsCompat.toBundle());
复制代码

能够看到一共能够设置四个Transition:布局

  • (1)setExitTransition() - 当A 跳转到 B时,A中的View退出场景的效果(默认Null)post

  • (2)setEnterTransition() - 当A 跳转到 B时,B中的View进入场景的效果(默认Fade)动画

  • (3)setReturnTransition() - 当B 返回 A时,B中的View退出场景的效果(默认同EnterTransition)ui

  • (4)setReenterTransition() - 当B 返回 A时,A中的View进入场景的效果(默认同ExitTransition)this

以上这个过程一样能够看作是Transition做用在Scene上的一系列效果,只不过这里的Scene从上一篇中的单一布局换成了Window。不过细心的同窗可能发现了,明明我为四个过程都设置动画效果,可为何ExitTransition没有生效呢?接下来咱们为每一个Transition加入监听,看看动画的执行流程。下面是其中一个的代码,其余三个都同样:spa

Explode explode = new Explode();
explode.setDuration(3000);
explode.setMode(Visibility.MODE_IN);
  explode.addListener(new Transition.TransitionListener(){
            @Override
            public void onTransitionStart(Transition transition) {
               
                Log.d("Transitions--","ReenterTransitionStart");
            }

            @Override
            public void onTransitionEnd(Transition transition) {
               
                Log.d("Transitions--","ReenterTransitionEnd");
            }

            @Override
            public void onTransitionCancel(Transition transition) {
                
            }

            @Override
            public void onTransitionPause(Transition transition) {

            }

            @Override
            public void onTransitionResume(Transition transition) {

            }
        });
   getWindow().setReenterTransition(explode);
复制代码

再次执行程序,日志信息以下: 3d

原来A页面的退出动画和B页面的进入动画、B页面的返回动画和A页面的重现动画是并行执行的。也就是说A页面的ExitTransition不是没有执行,而是在它执行的时候,B页面已经覆盖上来,而且EnterTransition已经同时在执行了,这时A页面已经不可见了。这也是Android默认的转场动画执行流程。 那问题来了,若是想要串行执行该怎么办呢? 有两种方法: 在设置Transition的时候同时设置不容许Transition重叠,也就是并行执行:

getWindow().setAllowEnterTransitionOverlap(false);
getWindow().setWindowAllowReturnTransitionOverlap(false);
复制代码

或者在主题文件全局设置这个属性,这样无疑更好,即减小了代码又保证了应用视觉效果的统一:

<item name="android:windowAllowEnterTransitionOverlap">false</item>
<item name="android:windowAllowReturnTransitionOverlap">false</item>
复制代码

修改后效果以下:

日志也显示如今是串行执行了:

生命周期分析

保持上面的打印信息不变,咱们增长两个Activity的生命周期日志信息,串行结果以下:

并行以下:

能够获得以下信息:

  • 在A页面的onPause执行前,ExitTransition就已经开始执行了
  • Transition不会阻塞BActivity的生命周期,尽管是串行执行的,即便ExitTransition没结束,BActivity已经执行完OnResume了。
  • ReturnExitTransition须要等到AActivity OnStart执行完才开始执行,并且ReturnExitTransition会阻塞AActivity的生命周期,AActivity的OnResume会等到ReturnExitTransition执行完再执行。关于这点能够简要说明下:直接调用Finish不会有动画直接结束掉,须要执行onBackPressed()才会有ReturnExitTransition。看源码就很明显了:
public void onBackPressed() {
        if (mActionBar != null && mActionBar.collapseActionView()) {
            return;
        }

        if (!mFragments.getFragmentManager().popBackStackImmediate()) {
            finishAfterTransition();
        }
    }

复制代码

总结

最后简单分析下转场动画的大体流程(以slide为例),看过上一篇文章的同窗应该很好理解:

1.从DecoerView开始,依次遍历得到当前Window上的视图树里的全部View

2.执行captureStartValues(TransitionValues transitionValues),捕获View开始状态的一些属性(visibility,Parent,LocationOnScree)

3.设置全部的VIew为INVISIBLE。

4.执行captureEndValues(TransitionValues transitionValues),捕获View结束状态的一些属性(visibility,Parent,LocationOnScree)

5.比较属性的不一样,建立属性动画。下一个过程就是返回属性动画并执行了。
复制代码

这是ExitTransiton的流程,其余三个也差很少。下一篇将会讲带共享元素的转场动画,也是material design中颇有特点的动画了。

相关文章
相关标签/搜索