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

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

Content Transition

Content Transition就是最常见的转场动画了。为了方便大家理解,我们先来上个图。

部分代码:

源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页面:

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

可以看到一共可以设置四个Transition:

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

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

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

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

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

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);
复制代码

再次执行程序,日志信息如下:

原来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中很有特色的动画了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值