Ⅵ. Transition Animation / 转场动画 & 共享元素

本节暂时未提供 Demo,如果想查看相关代码可以先参考项目 Material-Animations .

Material-Animations 项目的作者虽早已停止维护这个项目,但相关代码还能够参考。我也会尽快补上最新的 Demo。

1. 什么是 Transition?

安卓 5.0 中 Activity 和 Fragment 变换是建立在名叫 Transitions 的安卓新特性之上的。这个诞生于 4.4 的 transition 框架

为在不同的 UI 状态之间产生动画效果提供了非常方便的 API。

该框架主要基于两个概念:场景(scenes)和变换(transitions)。

场景(scenes)定义了当前的 UI 状态

变换(transitions)则定义了在不同场景之间动画变化的过程。

虽然 transition 翻译为变换似乎很确切,但是总觉得还是没有直接使用 transition 直观,为了更好的理解下面个别地方直接用 transition

代表变换。

当一个场景改变的时候,transition 主要负责:

(1)捕捉在开始场景和结束场景中每个 View 的状态。

(2)根据视图一个场景移动到另一个场景的差异创建一个 Animator。

在 Android 5.0 中 Transition 可以被用来实现 Activity 或者 Fragment 切换时的异常复杂的动画效果。虽然在以前的版本中,

已经可以使用 Activity 的 overridePendingTransition() 和 FragmentTransaction 的 setCustomAnimation() 来实现

Activity 或者 Fragment 的动画切换,但是他们仅仅局限与将整个视图一起动画变换。新的 Lollipop API更进了一步,让单独的 view

也可以在进入或者退出其布局容器中时发生动画效果,甚至还可以在不同的 activity/Fragment 中共享一个 view。

这里先看一张官方的效果图:

对转场动画更加详细的介绍可以查看官方介绍。

Transitions Framework 主要作用或者应用场景

可以在activity之间跳转的时候添加动画

动画共享元素之间的转换活动

activity中布局元素的过渡动画。

下面分别以这些场景一一介绍。

2. Transitions 在 Activity 切换过程中的效果

首先,我们回顾下,我们之前是如何设置 Activity 切换过程中的动画,毫无疑问,通过 overridePendingTransition,

更多具体实现请看 WIKI

或到实现 Activity 的切换动画

这里我们直接介绍通过 Transitions 实现的切换效果。

当从 Activity A 切换到 Activity B 的时候,Activity 布局的内容会按照预先定义好的动画来执行过渡动画。

在 android.transition 包中,已经有三种现成的动画可以用: Explode,Slide 和 Fade。所有这些过渡都会跟踪

Activity 布局中可见的目标 Views,驱动这些 Views 按照过渡的规则产生响应的动画效果。

Explode

Slide

Fade

你可以在 xml 中创建这些过渡效果,也可以通过代码来创建。对于 Fade 过渡效果来说,它看起来是这样子的:

在 style 中设置

在 style 中添加 android:windowContentTransitions 属性启用窗口内容转换( Material-theme 应用默认为 true ),

指定该 Activity 的 Transition

true

@transition/activity_fade

@transition/activity_slide

xml 中创建

过渡效果定义在 xml 中,目录是 res/transition

res/transition/activity_fade.xml

android:duration="1000"/>

res/transition/activity_slide.xml

android:duration="1000"/>

要使用这些 xml 中定义的过渡动画,你需要使用 TransitionInflater 来实例化它们。

MainActivity.java

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_transition);

setupWindowAnimations();

}

private void setupWindowAnimations() {

Slide slide = TransitionInflater.from(this).inflateTransition(R.transition.activity_slide);

getWindow().setExitTransition(slide);

}

TransitionActivity.java

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_transition);

setupWindowAnimations();

}

private void setupWindowAnimations() {

Fade fade = TransitionInflater.from(this).inflateTransition(R.transition.activity_fade);

getWindow().setEnterTransition(fade);

}

在代码中创建

MainActivity.java

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_transition);

setupWindowAnimations();

}

private void setupWindowAnimations() {

Slide slide = new Slide();

slide.setDuration(1000);

getWindow().setExitTransition(slide);

}

TransitionActivity.java

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_transition);

setupWindowAnimations();

}

private void setupWindowAnimations() {

Fade fade = new Fade();

fade.setDuration(1000);

getWindow().setEnterTransition(fade);

}

不管哪种创建方法都会产生如下的效果:

那么这里面一步一步的到底发生了什么:

Activity A 启动 Activity B

Transition Framework 发现 A 中定义了Exit Transition (slide) 然后就会对它的所有可见的View使用这个过渡动画.

Transition Framework 发现 B 中定义了Enter Transition (fade) 然后机会对它所有可见的Views使用这个过渡动画.

On Back Pressed(按返回键) Transition Framework 会执行把 Enter and Exit 过渡动画反过来执行(但是如果定义了

returnTransition 和 reenterTransition,那么就会执行这些定义的动画)

译注:

Exit Transition: 可以理解为 activity 进入后台的过渡动画

Enter Transition: 可以理解为创建 activity 并显示时的过渡动画

Return Transition:可以理解为销毁 activity 时的过渡动画

Reenter Transition: 可以理解为 activity 从后台进入前台时的过渡动画

要使这些过渡动画生效,我们需要调用 startActivity(intent,bundle) 方法来启动 Activity。bundle 需要通过

ActivityOptionsCompat.makeSceneTransitionAnimation().toBundle() 的方式来生成

ReturnTransition & ReenterTransition

Return and Reenter Transitions 是与进入和退出动画相对应的.

EnterTransition ReturnTransition

ExitTransition ReenterTransition

如果 Return or Reenter 没有创建, Android 会把 Enter and Exit Transitions 反过来执行. 但是如果你创建了

Return or Reenter,那 Android 就会执行你创建的动画,并且这些动画可以不同.

我们可以修改下前面 Fade 的例子,给 TransitionActivity 创建 ReturnTransition。这里我们就拿 Slide 过渡效果来举例子。

这样,如果我们从 B 返回到 A 的时候,B 就会执行一个 Slide 的过渡效果。

TransitionActivity.java

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_transition);

setupWindowAnimations();

}

private void setupWindowAnimations() {

Fade fade = new Fade();

fade.setDuration(1000);

getWindow().setEnterTransition(fade);

Slide slide = new Slide();

slide.setDuration(1000);

getWindow().setReturnTransition(slide);

}

可以看到,如果没有创建 Return Transition,退出的时候会执行 Enter Transtion 相反的动画。如果创建了 Return Transition,

那么就会执行这个创建的动画效果。

没有Return Transition

有Return Transition

Enter: Fade In

Enter: Fade In

Exit: Fade Out

Exit: Slide out

3. Activity 之间共享元素 (Share Elements)

这里的思想就是通过动画的形式将两个不同布局中的两个不同的View联系起来。

然后 Transition framework 就会在用户从一个View切换到另一个View的时候给用户展现一些必要的动画。

但你要记住:发生动画的View并不是从一个布局中移动到另一个布局。他们是两个独立的View。

3_a 设置 Window Content Transition 属性

你需要在 app 的 styles.xml 中进行设置.[ps]我没有设置也没问题

values/styles.xml

...

true

...

如果你愿意的话,你也可以给整个app设置一个默认的转场动画和共享元素动画。

...

@transition/explode

@transition/explode

@transition/changebounds

@transition/changebounds

...

3_b 设置相同的 transition name

为了使共享元素动画生效,你需要给共享元素的两个View设置相同的android:transitionName属性值。不过他们的id和其他属性可以不同。

layout/activity_a.xml

android:id="@+id/small_blue_icon"

style="@style/MaterialAnimations.Icon.Small"

android:src="@drawable/circle"

android:transitionName="@string/blue_name" />

layout/activity_b.xml

android:id="@+id/big_blue_icon"

style="@style/MaterialAnimations.Icon.Big"

android:src="@drawable/circle"

android:transitionName="@string/blue_name" />

3_c 用共享元素来启动 activity

使用 ActivityOptions.makeSceneTransitionAnimation() 方法指定要共享元素的 View 和

android:transitionName 属性的值

MainActivity.java

blueIconImageView.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Intent i = new Intent(MainActivity.this, SharedElementActivity.class);

View sharedView = blueIconImageView;

String transitionName = getString(R.string.blue_name);

ActivityOptions transitionActivityOptions = ActivityOptions.makeSceneTransitionAnimation(MainActivity.this, sharedView, transitionName);

startActivity(i, transitionActivityOptions.toBundle());

}

});

这样就可以有下面漂亮的过渡效果了:

可以看到, Transition framework 创建并执行了一个动画。动画的视觉效果就是一个View从一个activity移动到另一个activity中

并伴随着形状的变化。

4. 在 fragment 之间实现 Shared elements 过渡动画

这个activity中的做法几乎是一样的。

步骤 a) 和步骤 b)完全一样, 只有步骤 c)有点区别

4_c 启动带有共享元素的 fragment

在你使用 FragmentTransaction 启动 fragment 的时候,你需要同时带上共享元素过渡动画的先关信息。

FragmentB fragmentB = FragmentB.newInstance(sample);

// Defines enter transition for all fragment views

Slide slideTransition = new Slide(Gravity.RIGHT);

slideTransition.setDuration(1000);

sharedElementFragment2.setEnterTransition(slideTransition);

// Defines enter transition only for shared element

ChangeBounds changeBoundsTransition = TransitionInflater.from(this).inflateTransition(R.transition.change_bounds);

fragmentB.setSharedElementEnterTransition(changeBoundsTransition);

getFragmentManager().beginTransaction()

.replace(R.id.content, fragmentB)

.addSharedElement(blueView, getString(R.string.blue_name))

.commit();

最终的效果就是这样的:

5. 允许过渡效果之间的重叠

You can define if enter and exit transitions can overlap each other.

你可以设置一个 activity 的退出效果和另一个 activity 的进入效果产生重叠部分。

当设置为 true, enter transition 会立马执行>

当设置为 false, enter transition 会等到退出 exit transition 结束后再执行.

这对Fragments和Activities的共享元素过渡效果都是有用的。

FragmentB fragmentB = FragmentB.newInstance(sample);

// Defines enter transition for all fragment views

Slide slideTransition = new Slide(Gravity.RIGHT);

slideTransition.setDuration(1000);

sharedElementFragment2.setEnterTransition(slideTransition);

// Defines enter transition only for shared element

ChangeBounds changeBoundsTransition = TransitionInflater.from(this).inflateTransition(R.transition.change_bounds);

fragmentB.setSharedElementEnterTransition(changeBoundsTransition);

// Prevent transitions for overlapping

fragmentB.setAllowEnterTransitionOverlap(overlap);

fragmentB.setAllowReturnTransitionOverlap(overlap);

getFragmentManager().beginTransaction()

.replace(R.id.content, fragmentB)

.addSharedElement(blueView, getString(R.string.blue_name))

.commit();

可以看到,效果还是挺明显的:

Overlap True

Overlap False

Fragment_2 出现在Fragment_1的上面

Fragment_2 等到Fragment_1消失后才出现

6. 布局元素动画

6_1 Scenes (场景)

也可以用来驱动一个activity中的布局发生变化时,让其中的View产生过渡动画。

过渡效果发生在场景之间。场景就是一个定义了静态UI的普通布局。Transition Framework可以在两个场景之间添加切换过渡动画。

scene1 = Scene.getSceneForLayout(sceneRoot, R.layout.activity_animations_scene1, this);

scene2 = Scene.getSceneForLayout(sceneRoot, R.layout.activity_animations_scene2, this);

scene3 = Scene.getSceneForLayout(sceneRoot, R.layout.activity_animations_scene3, this);

scene4 = Scene.getSceneForLayout(sceneRoot, R.layout.activity_animations_scene4, this);

(...)

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.button1:

TransitionManager.go(scene1, new ChangeBounds());

break;

case R.id.button2:

TransitionManager.go(scene2, TransitionInflater.from(this).inflateTransition(R.transition.slide_and_changebounds));

break;

case R.id.button3:

TransitionManager.go(scene3, TransitionInflater.from(this).inflateTransition(R.transition.slide_and_changebounds_sequential));

break;

case R.id.button4:

TransitionManager.go(scene4, TransitionInflater.from(this).inflateTransition(R.transition.slide_and_changebounds_sequential_with_interpolators));

break;

}

}

上面的代码会在同一个activity中的4个场景切换时产生过渡动画。每一次切花的动画都是不一样的。

Transition Framework会考虑当前场景内所有可见的View并计算需出需要的动画来安排两个场景之间的view的位置。

6_2 布局的改变

也可以用来给布局属性的变化加上过渡效果。你只需要做你想要的改变然后其他的就交给Transition Framework,它会为你添加动画。

a) 开启演示过渡效果

下面这行代码告诉framework我们将要对UI进行一些改变,请你给我加上过渡效果。

TransitionManager.beginDelayedTransition(sceneRoot);

b) 改变布局参数

ViewGroup.LayoutParams params = greenIconView.getLayoutParams();

params.width = 200;

greenIconView.setLayoutParams(params);

改变View的宽度属性让他变小,这会触发layoutMeasure。这个点上,Transition framework会记录开始和结束时的相关值,

并给这个变化加上过渡效果。

附录

本文转载自

The address of the article in English:

Material-Animations

android 转场动画 共享元素,Android-Animation-Set相关推荐

  1. android 转场动画 共享元素,关于android:四步通过Glide实现共享元素无缝转场效果...

    读完这篇文章, 你就会晓得应用Glide等图片加载库实现共享元素转场成果,以及如何解决各种可能加载状态.通过共享转场动画,能够晋升利用交互体验,让用户应用起来更愉悦. 共享元素转场成果是Materia ...

  2. android 元素共享动画,android转场动画--共享元素(Shared Element)

    什么是共享元素呢?可以理解为当页面跳转是,看起来一个View属于界面A又属于界面B. 看一下下边这个效果: 在这个转场动画中,图片和文字都是共享元素,具体怎么实现这种效果呢? Step1 首先需要先在 ...

  3. Material Design之定制动画--触摸反馈,循环揭露,转场动画,共享元素和曲线运动

    先贴下官网的API https://developer.android.com/training/material/animations.html 触摸反馈: 在按钮属性中添加 android:bac ...

  4. android 转场动画 监听,Android 中的转场动画及兼容处理

    Android 中的动画有很多,除了在一个界面上使用帧动画.属性动画将一个或多个 View 进行动画处理以外,还可以用于两个界面之间过渡.跳转.在 Android 5.0 之前,我们已经有了 over ...

  5. android转场动画,让你的APP瞬间绚丽起来

    友好的交互体验能够吸引眼球,android API 21(5.0)后系统内置了Activity之间的切换动画,不仅可以让用户看起来舒服,而且实现起来也特别简单. 一.通过overridePending ...

  6. Android转场动画,Avtivity转场动画;

    转场动画 - 共享元素动画 先看效果: Activity1点击小图标开启Activity2: 开启Activity2效果就像是小图标放大了填充上去的,关闭Activity2回到Activity1时又像 ...

  7. android转场动画效果,Android转场动画

    Android最开始一个activity基本就是一个页面,但是没切换一次页面都要重新切换一个activity,这非常耗性能,并且随着平板的出现,更多时候我们只想切换一个页面的局部区域,因此fragme ...

  8. android 同根动画_[转载]Android anim动画切换效果

    关于动画的实现,Android提供了Animation,在Android SDK介绍了2种Animation模式: 1. Tween Animation:通过对场景里的对象不断做图像变换(平移.缩放. ...

  9. android图片缩放动画,Android动画共享元素(例列表图片放大到详情图片动画)

    一.什么是共享元素 简单来说共享元素就是两个Activity中都拥有此元素,在第二个Activity中进行强调而展示一些的动画效果.例如圆按钮的漂移动画.图片的放大动画. 二.为什么使用共享元素 主要 ...

  10. android 活动切换动画,android – 在使用ChangeImageTransform共享元素转换的两个活动之间动画化ImageView...

    要在具有共享元素的两个活动之间进行屏幕转换动画, 您可以阅读 this article并按照上述步骤: Enable window content transitions in your theme. ...

最新文章

  1. html默认选定,html默认代码
  2. android layoutparams,Android LayoutParams用法解析
  3. Android 高仿QQ5.2双向側滑菜单DrawerLayout实现源代码
  4. Python面向对象基础:编码细节和注意事项
  5. Java中对数组的排序方法总汇分析
  6. 山东CIO智库会员参观徐工信息公司
  7. 已经安装mysql xampp_windows 7 本机已安装mysql5的情况上 安装XAMPP
  8. textarea中输入多个空格或者换行时只显示一个空格的解决办法
  9. 【BZOJ 1491】 [NOI2007]社交网络
  10. 4. COM编程——IUnknown介绍
  11. mysql workbench首页_MySQL Workbench是干什么的?
  12. cisco产品命名规则
  13. php创建目录规则,php创建目录功能
  14. Postman下载及安装详细教程
  15. Oracle12C-针对log4j漏洞补丁修复
  16. synergy 控制客户端电脑很卡_Synergy 一套键鼠同时控制多台电脑的神器!超级方便!(开源免费,支持Win/Mac/Linux)...
  17. 阿里天池--宫颈癌检测(基于fastRCNN)新手初次尝试
  18. docker的代理配置_wuli大世界_新浪博客
  19. 深圳市专利代理机构名单(截至2016年3月)
  20. Laravel框架中使用 Repository 模式

热门文章

  1. maven helper解决依赖冲突问题
  2. mysql 修改登录用户名和密码
  3. springAOP 之 前置输出
  4. 列和相减 L3-L2
  5. 详细图解哈夫曼Huffman编码树
  6. centos 安装gcc
  7. jQuery新的事件绑定机制on()
  8. vsftp客户连接常见故障现象
  9. 5个CSS3技术实现设计增强
  10. Silverlight for KPI