Android Activity 切换动画及5.0以后的转场动画

学习收集,非原创

一、 简介

在Android开发过程中,经常会碰到Activity之间的切换效果的问题,下面介绍一下如何实现左右滑动的切换效果,首先了解一下Activity切换的实现,Android已经内置了几种动画效果,可以见 android.R.anim 类。一般情况下我们需要自己定义屏幕切换的效果。首先我们先了解Activity的位置定义,如下图:


图图图

从上图可以看出,以手机屏幕下面边未X轴,屏幕左边为Y轴,

  • 当Activity在X轴值为-100%p时,刚好在屏幕的左边(位置1),
  • 当X轴值为0%p时,刚好再屏幕内(位置2),
  • 当X=100%p时刚好在屏幕右边(位置3)。

清楚了位置后,我们就可以实现左右滑动的切换效果,首先让要退出的Activity从位置2移动到位置1,同时让进入的Activity从位置3移动位置2,这样就能实现从左右切换效果。
实现过程如下,首先定义2个动画,在 res目录创建anim目录, 然后在目录创建动画的xml文件:
out_to_left.xml (从左边退出动画)
in_from_right.xml(从右边进入动画)

out_to_left.xml (从 位置2 移动到 位置1)

<?xml version="1.0" encoding="utf-8"?>
  <set 
   xmlns:android="http://schemas.android.com/apk/res/android" 
  android:interpolator="@android:anim/accelerate_interpolator"> 
  <translate android:fromXDelta="0%p" 
   android:toXDelta="-100%p" 
   android:duration="500" />
 </set>
    in_from_right.xml (从 位置3 移动到 位置2)

    <?xml version="1.0" encoding="utf-8"?>
    <set 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:interpolator="@android:anim/accelerate_interpolator">
     <translate 
      android:fromXDelta="100%p" 
      android:toXDelta="0%p" 
      android:duration="500" />
    </set>

二 、使用windowAnimation和ActivityAnimation设置Android转场动画

1. windowAnimation和ActivityAnimation的区别:

显而易见,window与Activity本身从名字上就知道不同,但对于项目开发中 windowAnimation和ActivityAnimation的区别必须心领神会。
区别主要如下:

    1. windowAnimation包含: windowEnterAnimationwindowExitAnimation
      ActivityAnimation包含: android:activityOpenEnterAnimationandroid:activityOpenExitAnimationandroid:activityCloseEnterAnimationandroid:activityCloseExitAnimation
    1. 在项目中WindowAnimation的控制权大于Activity的控制权,即在Activity转场过程中,如果同时设置了WindowAnimation和ActivityAnimation,那么 可能(因为这种情况非常多) 只会执行WindowAnimation
    1. 对于WindowAnimation的定义很简单,在style.xml文件中只需要继承Animation Style即可
2. Android使用Theme自定义Activity进入退出动画

在AndroidManifest里面,对于application和activity标签可以定义theme属性。如果对Application定义了某一个属性,那么会对所有的activity产生影响,当然你可以在activity中覆盖它。

在AndroidManifestl中
对所有的activity产生影响
<application  android:theme="@style/AppTheme">
在activity中覆盖它
<activity
   android:name=".ui.video.VideoDetailActivity"
   android:label="@string/title_activity_video_detail"
   android:theme="@style/AppTheme"></activity>
在values/styles.xml中
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
        <item name="android:windowAnimationStyle">@style/myActivityOutEnterAnima</item>
    </style>

<style name="myActivityOutEnterAnima" parent="@android:style/Animation.Activity">
        <!-- 定义activity的进出场动画 -->
        <item name="android:activityOpenEnterAnimation">@anim/enter_from_right</item>
        <item name="android:activityOpenExitAnimation">@anim/out_to_left</item>
        <item name="android:activityCloseEnterAnimation">@anim/enter_from_left</item>
        <item name="android:activityCloseExitAnimation">@anim/out_to_right</item>
    </style>

在values/anim.xml中
enter_from_left.xml
enter_from_right.xml
out_to_left.xml
out_to_right.xml

android:activityOpenEnterAnimation:指的是进入B时, B的动画。
android:activityOpenExitAnimation:指的是进入B时,A的动画,与B的动画是一起显示的。
android:activityCloseEnterAnimation:通过B跳转到C后,后退到B时,B的进入动画
android:activityCloseExitAnimation:通过B跳转到C后,后退到B时,C的退出动画'

这样就可以了,至于anim中的动画,就自己定义啦,这个和普通的animation是一样的,如果不知道的话,请参见http://developer.android.com/guide/topics/graphics/view-animation.html
这种方式除了可以定义activity的animation之外,还有task,window出现和结束时候的动画,具体请参见
http://developer.android.com/reference/android/R.styleable.html#WindowAnimation

从上述2中动画的定义上来看,显然ActivityAnimation更为复杂,但这种复杂带来的转场效果非常好,可以同时控制2个Activity的动画,而不像WindowAnimation只能控制下一个Activity的窗体动画。

三、 窗体动画也可以使 Activity. overridePendingTransition来设置

从Android2.0开始在Activity增加了一个方法:
public void overridePendingTransition (int enterAnim, int exitAnim) 其中:

  • enterAnim 定义Activity进入屏幕时的动画
  • exitAnim 定义Activity退出屏幕时的动画

注:overridePendingTransition 方法必须在startActivity()或者 finish()方法的后面。当时没法定义退出的动画

四、 5.0以后的转场动画

1. 概述

毫无疑问,动画效果能提高用户体验。我们平时使用最多的动画基本上是属性动画和补间动画了,属性动画很强,基本能定制我们想要的动画,但是你是否知道,API 21(5.0)后系统内置了Activity之间的切换动画,而且非常酷炫,今天我跟大家一起分享一下。

我们知道,在两个Activity之间切换,我们一般会写出类似下面的代码:

在API 21以后,我们可以使用内置的Activity切换动画啦。

但是这样也就意味着只能兼容5.0之后的系统,我们先看一个效果图来压压惊:

先看看第一个Activity,退出时用的是Explode效果,第二个Activity进入时用的是Slide效果。

这些效果无需我们自己去实现,都是内置的效果,我们所编写的代码几乎为零,接下来我们一一看看内置了哪些效果。

2.使用内置Activity切换动画的步骤

Activity之间的切换期间,对于某个Activity来说,无非就是“进入”和“退出”两种情景下的动画。
而“进入”分为“第一次进入Activity”和“返回当前Activity”这两种情况。

另外系统还提供了一种动画,即共享元素,这是让两个Activity中的View有个过渡切换的效果。
执行动画的状态如下所示:

  • enter:用于决定第一次打开当前Activity时的动画

  • exit : 用于决定退出当前Activity时的动画

  • reenter: 用于决定如果当前Activity已经打开过,并且再次打开该Activity时的动画

  • shared elements:用于决定在两个Activity之间切换时,指定两个Activity中对应的View的过渡效果

那么应该怎么去使用Activity切换动画呢?

我们看看使用步骤:
  • ** 首先在setContentView()之前执行,用于告诉Window页面切换需要使用动画接下来就是加载切换动画**
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
  • 接下来就是加载切换动画
    其中R.transition.explode就是要执行的动画,是在res/transition目录下的xml文件,我们使用的是系统内置的Explode效果动画,关于怎么去写explode.xml,我们接下来小节去讲解。
  • 告诉Window,当前的Activity在什么情况下使用上面的动画
    上面我们创建好了切换动画,接下来就是要告诉当前窗口,在什么情况下去使用动画效果啦,你可以根据你的需求在不同的切换情景中选择不同的效果:

当然了,你也可以不使用代码的方式,直接在你使用的主题

  • 调用startActivity
    跟我们之前使用的startActivity(Intent intent);不同,这里多了一个参数Bundle,我们是先通过makeSceneTransitionAnimation函数创建一个ActivityOptions对象,再将其转为Bundle对象:

整体使用步骤就是以上这些,是不是很简单?接下来我们去学习如何使用内置动画~

3.使用内置动画

3.1 Explode效果

Explode即爆炸效果,使用Explode效果很简单,在res/transition目录下新建一个xml文件(如explode.xml),内容如下:

<explode  
  xmlns:android="http://schemas.android.com/apk/res/android"   
  android:duration="300" />

其中duration表示Explode动画持续时间,由于是Activity之间的切换,最好不要把动画时间设置过大,一般取200~500毫秒比较合适。

我们看看效果吧~


3.2 Slide效果

即滑动效果,使用Slide跟Explode类似,都是在res/transition目录下新建一个xml文件(如slide.xml),内容如下:


图呢??

其中,slideEdge表示起始滑动的侧边位置,end表示右侧,start表示左侧,top表示顶部,bottom表示底侧,各种效果你可以亲自试试~,一起看看滑动效果吧:


GIF 效果看的比较死板,可以下载我的源码实际运行一下~

如果你不希望顶部的状态栏以及底部的导航栏一起执行动画,可以在xml中指定:


3.3 Fade效果

Fade效果即淡化效果,使用淡化效果依然是很简单,在res/transition目录下新建一个xml文件(如fade.xml),内容如下:

<fade    
   xmlns:android="http://schemas.android.com/apk/res/android" 
   android:duration="300" />

Fade效果就是将View逐步淡化,这里不再贴效果啦,想看效果的可以下载我的源码运行看看~

3.4 Shared Element效果

即共享元素效果,与前面几种效果不同的是,共享元素效果是将前面一个Activity的某个子View与后面一个Activity的某个子View之间有过渡效果,我们先看看动态图感受一下:

从动态图中看到,第一个Activity的小绿色方块到第二个Activity大绿色方块有个过渡效果~

接下来我们重点看看如何实现这个效果。

如何实现Shared Element效果

1.将两个Activity中需要过渡的View加上Android:transitionName属性

两个View的android:transitionName属性取值要一致,比如:
第一个Activity布局:

第二个Activity布局:

两个绿色的View都添加android:transitionName属性,并且取名一致。

2.调用startActivity

ActivityOptions的makeSceneTransitionAnimation函数第一个参数Activity没啥解释的,第二个参数就是第一个Activity中的View对象,第三个参数就是两个Activity的View的 android:transitionName属性的值。


现在就可以实现这种Shared Element效果啦,但是可能你会想实现同时让两个View有这样的效果,可是makeSceneTransitionAnimation函数却只能让我们设置一个View和一个transitionName属性。

如何添加多个呢?

接下来我们一起学习让多个View同时有切换效果。
除了需要将两个Activity中需要过渡的View对应取相同的名称外,还需将需要过渡的View和transitionName取值对应的String这两个对象封装到一个Pair对象中:

然后调用ActivityOptionsCompat类的makeSceneTransitionAnimation的另一个重载函数:

makeSceneTransitionAnimation(Activity activity,  Pair<View, String>... sharedElements)

第一个参数不解释,后面参数为不定长度的形参,即你可以传递任意多个Pair对象。

最后调用startActivity

ActivityCompat.startActivity(this, intent, transitionActivityOptions.toBundle());

说了这么多步骤,我们来看看效果吧~

自定义 Shared Element切换动画

如果你对内置的 Shared Element还不够满意,你还可以定制View的过渡切换效果。

步骤如下

1.创建一个View的过渡移动的轨迹路径PathMotion类

我们可以创建ArcMotion对象,ArcMotion是PathMotion子类,是个曲线路径。想要了解更多ArcMotion可以查看:
ArcMotion官方文档

ArcMotion arcMotion = new ArcMotion();
arcMotion.setMinimumHorizontalAngle(50f);
arcMotion.setMinimumVerticalAngle(50f);

2.定义ChangeBounds类

我们自定义一个继承ChangeBounds的类,主要重写createAnimator函数,即创建你要执行的动画。这个函数由3个参数:

  • ViewGroup sceneRoot:屏幕根View,即DecorView,第二个Activity的DecorView

  • TransitionValues startValues :属性动画的起始属性值,TransitionValues 对象内部有各Map类型的属性values,用于保存需要执行属性动画的属性。这个里面的属性值是在函数captureStartValues里放置,因此你可以重写captureStartValues函数,并把你自定义的属性动画中的属性放进去。

  • TransitionValues endValues:与startValues类似,表示属性动画结束时的属性值。可以通过重写captureEndValues函数,并把你自定义的属性动画里面的最终属性值放进去。

我们先看一个最简单的示例:


看看效果吧~

最后5.0这部分借鉴(copy)于两位大神,仅作为个人学习参考资料,如有侵权告知立删除,附源图如下

5.0部分原创公众号
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,585评论 4 365
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,923评论 1 301
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,314评论 0 248
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,346评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,718评论 3 291
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,828评论 1 223
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,020评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,758评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,486评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,722评论 2 251
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,196评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,546评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,211评论 3 240
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,132评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,916评论 0 200
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,904评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,758评论 2 274

推荐阅读更多精彩内容