用户界面经常随着用户输入和其他事件而改变。例如,当用户输入查询条件并提交后可以隐藏查询表单。
为了在这些情况下使视觉上连续,我们可以使用动画来实现。这些动画可以给用户操作反馈并且帮助他们了解你的应用是怎么工作的。
Android包含transitions框架,可以很容易就让我们在两个view之间实现动画。这个框架在运行时随着时间改变它们的属性值来实现动画。它包含了内置的一些常用动画效果,你也可以创建自定义动画和回调。
这篇文章介绍了如何使用transitons框架的内置动画来实现动画和自定义动画。
1.Transitions框架
这个框架包含以下关键特征:
Group级别动画
可以给一个view层级中的所有view应用一个或多个动画效果
过渡型动画
基于view属性值的改变实现动画
内置动画
包含一些定义好的常用动画效果(如渐出和移动)
支持资源文件
可以通过资源文件加载view层级和内置动画
生命周期回调:
提供动画过程的回调
概述
transitions框架与view层级和动画共同作用。ttransitions框架的目的是存储view层级的状态,改变这些view层级从而改变界面,并且通过存储和应用动画定义用你动画实现这种改变。
下图说明了view层级,transitions框架和动画的关系:
![](https://developer.android.com/images/transitions/transitions_diagram.png)
transitions框架提供了scenes抽象类,transitions和transition managers。它们在接下来会介绍。使用这个框架,我们为想要实现动画的view创建scenes。然后为你想使用的动画创建transition。为了开启动画,使用transition manager声明要使用的transition和ending scene。
Scenes
scene储存了一个view层级的状态,包含它所有的view和它们的属性值。一个view层级可以是一个简单的view或一个viewgroup。在scene中储存view层级状态可以让我们从其他scene过渡到此状态。
transition框架使我们可以从布局资源文件或代码中的ViewGroup对象创建scenes。
在大多数情况下,我们不需要显式地创建starting scene。如果你应用了一个transition,框架会使用上一个ending scene作为随后transition的starting scene。如果之前未使用transition,框架会从当前屏幕状态收集view的信息。
当我们改变scene时scene可以定义它自己的操作。例如,当我们过渡到一个场景时想要清理view设置时这非常有用。
Transitions
在transitions框架中,动画创建了一系列frames。动画相关信息存在Transiton对象中。通过TransitionManager使用Transition。框架可以在俩个scene中实现过渡,或对一个scene过渡到不同的状态。
框架提供了一系列内置transition实现常用动画效果,如渐入和 改变大小。我们可以使用框架提供的API实现自定义的过渡效果。我们还可以组合不同的动画效果。
Transition的生命周期和activity的生命周期类似。
2.创建Scene
Scenes存储view的状态,包含它所有的view和它们的属性值。transitions框架在一个起始scene和结束scene间运行动画。起始scene经常由当前UI状态生成。对于结束scene,框架允许我们从资源文件和代码中生成scene。
从布局文件创建Scene
你可以直接从布局资源文件创建一个Scene实例。当view是静态时使用这种创建方法。生成的scene代表了创建Scene实例时view的状态。如果你改变了view,必须重新生成scene。框架将文件中整个view层级生成scene,而不能从文件局部生成。
为了从资源文件生成Scene实例,从布局中获取根作为一个ViewGroup,然后调用Scene.getSceneForLayout()方法,root和布局资源ID作为参数。
定义Scenes布局
以下代码展示了用同一个scene根元素创建俩个不同的scene。
这个例子包含以下布局定义:
- activity的主布局,包含一个textview和子布局
- 用于生成第一个scene的布局,包含俩个textview
- 用于生成第二个scene的布局,包含俩个textview,但顺序不同
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/master_layout">
<TextView android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title" />
<FrameLayout android:id="@+id/scene_root"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<include layout="@layout_a_scene"/>
</FrameLayout>
</LinearLayout>
res/layout/a_scene.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scene_container"
android:layout_width="match_parent" android:layout_height="match_parent">
<TextView android:id="@+id/text_view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text Line 1"/>
<TextView android:id="@+id/text_view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text Line 2"/>
</RelativeLayout>
res/layout/another_scene.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scene_container"
android:layout_width="match_parent" android:layout_height="match_parent">
<TextView android:id="@+id/text_view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text Line 2"/>
<TextView android:id="@+id/text_view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text Line 1"/>
</RelativeLayout>
从布局生成Scenes
在创建2个布局后,你能为每一个生成scene。这让你可以之后在俩个UI配置中过渡。
Scene mAScene;
Scene mAnotherScene;
// Create the scene root for the scenes in this app
mSceneRoot = (ViewGroup) findViewById(R.id.scene_root);
// Create the scenes
mAScene = Scene.getSceneForLayout(mSceneRoot, R.layout.a_scene, this);
mAnotherScene =
Scene.getSceneForLayout(mSceneRoot, R.layout.another_scene, this);
在代码中创建Scene
你可以在代码中创建用ViewGroup生成Scene实例。当你直接在代码中修改view层级或动态生成Scene时可以使用这种实现。
在代码中生成Scenne实例时,使用Scene(sceneRoot, viewHierarchy)构造器。
Scene mScene;
// Obtain the scene root element
mSceneRoot = (ViewGroup) mSomeLayoutElement;
// Obtain the view hierarchy to add as a child of
// the scene root when this scene is entered
mViewHierarchy = (ViewGroup) someOtherLayoutElement;
// Create a scene
mScene = new Scene(mSceneRoot, mViewHierarchy);
3.应用Transition
在transition框架中,动画创建一系列frame。框架使用transition对象代表这些动画,包含动画信息。运行一个动画,你提供要使用的transition和ending scene给transition manager。
创建一个Transition
一旦你定义了starting scene和ending scene,你需要创建一个Transition对象定义一个动画。框架让你可以在资源文件中声明一个内置transiton然后在代码中加载,或者直接在代码中创建内置transition实例。
Table 1. Built-in transition types.
Class | Tag | Attributes | Effect |
---|---|---|---|
AutoTransition | <autoTransition/> | - | Default transition. Fade out, move and resize, and fade in views, in that order. |
Fade | <fade/> | android:fadingMode="[fade_in | | fade_in fades in viewsfade_out fades out viewsfade_in_out (default) does a fade_out followed by a fade_in . |
ChangeBounds | <changeBounds/> | - | Moves and resizes views. |