android - 动画视图使用场景和过渡(文档学习)

发表于:,更新于:,By Sally
大纲
  1. 1. 动画视图使用场景和过渡 Animating Views Using Scenes and Transitions
  2. 2. 转化框架 The Transitions Framework
    1. 2.1. 场景 Scenes
      1. 2.1.1. 使用布局文件创建场景 Create a Scene From a Layout Resource
      2. 2.1.2. 使用代码创建场景 Create a Scene in Your Code
    2. 2.2. 创建场景动作 Create Scene Actions
    3. 2.3. 过渡 Transitions
      1. 2.3.1. 从资源文件创建transition实例 Create a transition instance from a resource file
      2. 2.3.2. 在代码中创建transition实例 Create a transition instance in your code
    4. 2.4. 应用一个过渡 apply a transition
    5. 2.5. 选择特定的目标视图 choose specific target views
    6. 2.6. 指定多个过渡 specify multiple transitions
    7. 2.7. 不使用场景的情况下使用过度 Apply Transition Without Scenes
    8. 2.8. 局限性 Limitations

动画视图使用场景和过渡 Animating Views Using Scenes and Transitions

活动的用户界面会经常改变来响应用户的输入或其他事件。例如,一个活动,其中包含一个表单,用户可以在该表单键入搜索查询,当用户提交表单时,隐藏当前的表单并显示搜索结果列表。

在这些情况下,你可以在用户界面中的不同视图层次结构之间进行动画改变,从而提供视觉上的连续性。当用户执行操作时,这些动画会给用户反馈并帮户他们了解该应用是如何工作的。

安卓包含过渡框架(transitions framework),它使得你能够轻松的在两个视图层次之间进行动画改变。该框架进行动画处理是通过在运行时改变视图的一些属性值。框架包含一些通用效果的内置动画,同时它也允许你创建自定义动画以及过度生命周期回调。

转化框架 The Transitions Framework

应用程序用户界面的动画效果提供的不仅仅是视觉上的吸引力。动画突出变化并且提供视觉线索,来帮助用户了解你的应用程序是如何工作的。

安卓提供了过渡框架,来帮助你在一个视图层次结构和另一个视图层次之间进行动画。框架可以应用一个或多个动画到视图层次结构中的所有视图,作为他们之间的变化。

框架有一下几个特点:

  • 组级别的动画

    应用一个或多个动画效果到视图层次结构中的所有视图。

  • 过渡动画

    runs animations based on the changes between strting and ending view property values.

  • 内置动画

    包含一些与定义的通用动画效果。像:淡入淡出,移动。

  • 支持资源文件

    从资源文件加载视图层次结构和内置动画。

  • 生命周期回调

    定义动画以便更好的控制动画以及层次结构变化过程。

场景 Scenes

创景用来存储视图层次结构的状态,包括所有的视图以及他们的属性值。一个视图层次结构可以是一个简单的view或者一个复杂的view树和子布局。保存场景的视图层次结构状态可以使得你从别的场景转换到该场景的状态。框架提供了Scene类来代表场景。

使用布局文件创建场景 Create a Scene From a Layout Resource

Scene.getSceneForLayout()

  • 布局文件

res/layout/activity_main.xml

1
2
3
4
5
6
7
8
9
10
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/master_layout">

<TextView
android:id="@+id/title"
android:text="Title" />

<FrameLayout
android:id="@+id/scene_root"
<include layout="@layout/a_scene">

</FrameLayout>
</LinearLayout>

这个布局包含了text field和一个作为场景根的子布局。第一个场景布局已经包含在了主布局文件中。这是的应用在初始化用户界面时就将该场景作ui的一部分展示并且将其加载到场景中。因为框架仅能够加载整个布局文件到场景。

res/layout/a_scene.xml

1
2
3
4
5
6
7
8
9
10
11
<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:text="Text Line 1" />
<TextView
android:id="@id/text_view2"
android:text="Text Line 2" />
</RelativeLayout>

第二个场景布局包含相同控件,两个text fields(id也相同),只是调整了一个放置顺序。

res/layout/another_scene.xml

1
2
3
4
5
6
7
8
9
10
11
<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:text="Text Line2" />
<TextView
android:id="@+id/text_view1"
android:text="Text Line1" />
</RelativeLayout>

从布局文件声称场景

1
2
3
4
5
6
7
8
9
Scene mAScene;
Scene mOtherScene;

// 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);

使用代码创建场景 Create a Scene in Your Code

Scene(sceneRoot, viewHierarchy) Scene.getSceneForLayout()

你可以在代码中通过ViewGroup对象创建场景实例。使用这个技巧你可以直接在代码中修改视图层级结构or可以动态声称视图层级结构。

1
2
3
4
5
6
7
8
9
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) someOtherLayoutEloement;

// create a scene
mScene = new Scene(mSceneRoot, mViewHierarchy);

创建场景动作 Create Scene Actions

Scene.setEnterAction() Scene.setExitAction()

自定义场景动作,将动作定义为Runnable对象,并将其传递到Scene.setExitAction()orScene.setEnterAction()方法。框架会在执行过渡动画之前调用setExitAction()方法进入场景,在执行过渡动画之后调用setEnterAction()方法结束场景。

不要使用场景动作在开始和结束场景的两个视图之间传递数据。更多信息,查看defining transition llifecycle callbacks。

过渡 Transitions

Table1. Built-in transition types

Class Attributes Effect
AutoTransition = Default transition. Fade out,move and resize, and fade in views, in that order.
Fade android:fadingMode=”[fade_in|fade_out|fade_in_out]” fade_in fades in views; fade_out fades out views; fade_in_out(default) does a fade_out followed by a fade_in.
ChangeBounds = Moves and resizes views.

从资源文件创建transition实例 Create a transition instance from a resource file

这种手法允许你在不改变activity的代码的情况下修改过渡定义。这种技术也有助于从应用程序代码中分离出复杂的transition定义,查看Specify Multiple Transitions

三个步骤:

  • 在项目中添加 res/transition/ 文件夹

  • 在该文件夹下创建新的xml资源文件

  • 为内置的transition添加xml节点

res/transition/fade_transition.xml

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

从资源文件中获得transition实例

1
Transition mFadeTransition = TransitionInflater.from(this).inflateTransition(R.transition.fade_transition);

在代码中创建transition实例 Create a transition instance in your code

1
Transition mFadeTransition = new Fade();

应用一个过渡 apply a transition

1
TransitionManager.go(mEndingScene, mFadeTransition);

选择特定的目标视图 choose specific target views

默认情况下,框架将过渡开始和结束场景中所有的视图。某些情况下,你也许只想讲动画应用到场景视图的一个子集。例如:框架不支持动画更改ListView对象,所以你不应该尝试通过动画过渡他们。框架允许你选择要动画的特定视图。

要过渡动画的每一个视图称为target。你可以只选一个与场景相关联的视图层次结构的一部分作为目标。

在开始过渡之前调用removeTarget()方法,可以从targets的list中移除一个或多个视图。添加一个你指定的视图到targets的list中,调用addTarget()方法。

指定多个过渡 specify multiple transitions

为了从一个动画中得到最好的影响,你应该讲它与场景之间发生变化的类型进行匹配。例如:如果你在场景之间添加移除一些视图并添加其他视图,淡入淡出动画就提供了显著的指示表示一些视图不在可用;如果你在一个屏幕上移动视图到不同的点,一个更好的选择是使用移动动画,以便用户可以留意到视图的新位置。

从xml中的过渡集合来定义过渡集,在res/transitions/文件夹中创建一个资源文件,在transitionSet元素下列出所有的过渡。例如:下面的例子展示了如何指定包含一些行为的动画集,作为AutoTransition类:

1
2
3
4
5
6
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
android:transitionOrdering="sequential">

<fade android:fadingMode="fade_out" />
<changeBounds />
<fade android:fadingMode="fade_in" />
</transitionSet>

在activity中通过调用TransitionInflater.from()方法来找出transition set保存在TransitionSet对象中。TransitionSet类继承自Transition类,so you can use it with a transition manager just like any other Transition instance.

不使用场景的情况下使用过度 Apply Transition Without Scenes

=_=|||

局限性 Limitations

transitions框架一些已知的局限性:

  • 将动画应用到SurfaceView上可能不会正确的显示。SurfaceView实例是通过非ui线程更新的,所以更新操作可能是与其他视图的动画不同步的。

  • 应用到TextureView上时,一些特定的过渡类型可能不会产生预期的动画效果。

  • AdapterView的子类,如ListView,管理他们子视图的方法与transitions框架不兼容。如果你试图在基于AdapterView的视图上执行动画,设备显示可能会挂。

  • 如果你试图使用动画改变TextView的大小,在tv对象完成层改变大小之前,文本可能弹出到一个新的位置。为了避免这个问题,不要使用动画去改变一个包含文本的textview的大小。