一种新的Activity转换动画实现方式

泡在网上的日子 / 文 发表于2015-07-10 20:14 第次阅读 动画,Activity

原文:http://codethink.me/2015/06/21/a-new-implementation-of-activity-transition-animations/?

0. 前言

为Android中基本的View组建Activity设置转换动画的方式一般有两种:通过overridePendingTransitions设置,以及使用TransitionManager实现。overridePendingTransitions只能使用XML来设置Activity的进入和退出动画,局限性很大。而使用TransitionManager只兼容API level 19及以上的设备。最近在?InstaMaterial concept?(这个系列文章本站有完整译文 见:InstaMaterial概念设计? )中发现其利用addOnPreDrawListener方法,提供了一种新的Activity转换动画实现方式,这里详细记录下这种基于addOnPreDrawListener()的实现方式。

1. 实现展开动画

首先创建一个基本的Activity转换场景,去掉默认的转换动画,没有任何动画的Activity转换效果如下。


修改第二个Activity的布局activty_second,设置最顶层的布局id为root。之后,在SecondAcivity的onCreate中,为root设置动画,核心部分代码如下:

@Override
public?void?onCreate(Bundle?savedInstanceState)?{
????super.onCreate(savedInstanceState);

????setContentView(R.layout.activity_second);

????rootView?=?findViewById(R.id.root);

????if?(savedInstanceState?==?null)?{
????????rootView.getViewTreeObserver().addOnPreDrawListener(new?ViewTreeObserver.OnPreDrawListener()?{
????????????@Override
????????????public?boolean?onPreDraw()?{
????????????????rootView.getViewTreeObserver().removeOnPreDrawListener(this);
????????????????startRootAnimation();
????????????????return?true;
????????????}
????????});
????}
}

这里需要注意的是: 1)只需要在首次创建时执行动画,因此需要满足条件savedInstanceState == null;2)在onPreDraw中要首先移除OnPreDrawListener,否则在动画过程中会多次调用,导致死循环。
最后,startRootAnimation的实现如下:

private?void?startRootAnimation()?{
????rootView.setScaleY(0.1f);
????rootView.setPivotY(rootView.getY()?+?rootView.getHeight()?/?2);

????rootView.animate()
????????????.scaleY(1)
????????????.setDuration(1000)
????????????.setInterpolator(new?AccelerateInterpolator())
????????????.start();
}

此时的动画效果如下:


2. 设置Activity透明背景

上面的动画还有一个问题:第二个Activity展开的时候,它的背景不是第一个Activity,而是白色背景,这是因为默认的主题为每个Activity设置了白色作为窗口的背景,因此需要在style中创建一个背景为透明的主题,并在AndroidManifest.xml中设置SecondActivty的主题为透明背景主题。
透明背景主题代码如下:


????@android:color/transparent
????true
????@null

最后的效果如下:


3. 小结

至此实现了一个简单的基于addOnPreDrawListener的转换动画,这种转换动画相对于overridePendingTransitions更为灵活,提供了更多想象空间,同时相比于TransitionManager有更好的兼容性。

这种方式目前存在的问题是需要为顶级view以及各层子view分别设置动画,使得顶级view和子view同时展开,或子view延后展开(否则会出现子view已经绘制到目标位置,顶级view仍然在执行动画的情况),对于复杂的布局而言实现有些繁琐。


上一篇:Android 开发有哪些新技术出现?
Android 的发展确实太快了,每年的都有很多新东西出现,想要覆盖所有新东西感觉也不太可能,我这里主要说一下主要的 Android 的主要新技术发展,其实了解 Android 的发展趋势,可能对开发者更有帮助。 开发工具 Android Studio: Google 官方放弃 Eclipse 和
下一篇:InstalMaterial学习笔记之Reveal效果
本文记录 开源项目 InstalMaterial 学习到的Reveal效果 国内有对应博客的 翻译 先看一下效果图: 最后效果图 惯例,不过这次是我学到了什么 对自定义属性使用属性动画 属性动画,get方法不一定需要 最重要的是ViewTreeObserver.OnPreDrawListener()的使用,另一