Transitions框架学习(二) —— 应用转场效果

在Transitions框架中,动画将创建一系列帧来描述视图结构从开始场景到结束场景的变化。视图框架通过Transition对象来代表这些动画,其中包括了动画的相关信息。要执行一个动画效果,需要向transitionManager(转场管理器)提供要使用的转场对象和和结束场景。

本节将讲解在两个场景之间使用内置的转场效果来实现移动、缩放和渐隐效果。下一节将介绍如何自定义转场效果。

创建一个转场

上一篇介绍了如何创建一个场景来代表视图结构的不同状态。创建了开始场景和结束场景之后还需要创建一个转场对象来定义切换过程中的动画效果。
框架支持在资源文件中指定内置的转场效果或者在代码中直接创建一个转场效果。
内置转场效果包括:

Transitions框架学习(二) —— 应用转场效果_第1张图片

通过资源文件创建转场

使用该种方式可以在不改变任何代码的情况下修改转场效果。还可以避免在代码中引入非常复杂的转场操作。

要通过资源文件指定一个内置的转场效果,请按以下步骤:

  1. 为工程添加res/transition/目录。
  2. 在该目录中创建一个新的XML文件。
  3. 在XML文件中添加一个内置的转场。

例如,如下资源文件指定了渐隐渐显转场:
res/transition/fade_transition.xml

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

以下代码演示如何通过资源文件在代码中获取一个Transition实例:

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

通过代码创建转场

如果需要在代码中动态修改用户界面并应用转场可以使用该种方法。

要创建一个内置的转场效果,调用Transition类的子类的构造器即可。例如,以下代码创建了一个渐隐转场的实例。

Transition mFadeTransition = new Fade();

应用一个转场

典型的做法是响应某个事件(例如一个用户操作)来对不同的视图结构应用转场。例如,考虑一个搜索用应用:当用户键入搜索关键字并点击搜索按钮时,应用切换场景到搜索页面,在切换的过程中应用动画,搜索按钮渐隐消失,搜索结果渐显出现。

要响应某个事件并执行一个应用动画效果的场景切换,只要在结束场景中调用TransitionManager.go()这个静态方法即可,如下代码演示了这一操作:

TransitionManager.go(mEndingScene, mFadeTransition);

框架会把视图结构中的场景根视图替换为结束场景,同时执行转场动画。开始场景是上一个转场效果的结束场景,如果之前没有执行过转场,开始场景就自动被设定为用户界面的挡前状态。

如果没有指定转场对象,transitionManager会使用自动转场效果。

指定目标View

默认情况下框架会将转场效果应用于开始场景和结束场景中的全部View。
某些情况下,可能只需要对场景中的某些View应用动画效果。例如,框架不支持对ListView对象应用转场效果,所以需要在执行转场的时候排除它们。框架允许选择特定的某些View执行转场效果。

应用转场效果的每个View被称作一个Target(目标)。只能选择跟场景相关的视图结构中的一部分作为目标。

如果要移除目标列表中的一个或多个View,在转场开始之前调用 removeTarget()方法即可。要把指定的View加入到目标列表中,调用addTarget()方法即可。

指定多种转场效果

为了能够让动画获得最好的效果,需要让动画的类型和场景的变化相契合。
例如,如果要在场景切换时移除一些View并添加另一些View,渐隐/渐显动画可以提供一种明显的指示:一些View不再可用了。如果要改变View在屏幕中的位置,那么执行一个移动动画会是一个好的选择,用户会很容易注意到View的位置发生了改变。

不必局限于只使用一种动画效果,框架允许组合多个内置或自定义动画效果成为一个Transition Set(转场集)。

如果需要在XML文件中创建一个转场集,在res/transitions/目录中将这些转场置于transitionSet根节点下即可。以下代码演示了如何创建一个与默认转场效果一样的转场集:

<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>

调用TransitionInflater.from()方法在代码中通过资源文件获取一个TransitionSet对象。TransitionSet类继承于Transition类,所以TransitionManager可以像处理Transition对象一样处理TransitionSet对象。

不使用场景应用转场效果

改变视图结构并不是改变用户界面的唯一方式。同样可以对当前视图结构添加、修改、删除子view的方式来改变界面。例如,需要只使用一个布局文件来实现搜索交互。开始时显示一个布局,其中包括一个关键字输入框和一个搜索按钮。如果需要把界面变为显示搜索结果,只需要在用户点击搜索按钮时调用ViewGroup.removeView()方法移除搜索按钮即可,之后在调用ViewGroup.addView()方法添加搜索结果。

在两个视图结构非常类似的时候,可能需要使用这种方式。对用户界面的小变化,没必要创建两个单独的布局文件,而只需要一个包含了视图结构的布局文件,相应的改变可以在代码中实现。

如果使用这种方式来改变布局结构,就没有必要创建场景。取而代之的是,可以在同一个视图结构的两种状态之间应用延迟转场。框架可以把当前的视图结构状态记录为初始状态,记录下其中的View发生的各种改变,然后当用户界面被重绘时对这些改变应用转场效果。

在单独的试图结构中创建一个延迟转场的步骤如下:

  1. 当事件激发了转场时,调用TransitionManager.beginDelayedTransition()方法,传递应用转场效果的所有View的共有父视图作为参数。框架会记录当前所有子View的状态和它们的属性值。
  2. 对子View进行需要的变换操作。框架会记录对子View所做的这些改变以及它们的属性值。
  3. 当系统根据改变重绘用户界面时,框架会对之前状态和当前的新状态之间应用转场。
    以下例子演示了如何对一个被添加到视图结构中的TextView对象应用延迟转场,首先展示的布局文件:
    res/layout/activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mainLayout" android:layout_width="match_parent" android:layout_height="match_parent" >
    <EditText  android:id="@+id/inputText" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_width="match_parent" android:layout_height="wrap_content" />
    ...
</RelativeLayout>

以下代码演示了如何为添加TextView添加动画效果:

private TextView mLabelText;
private Fade mFade;
private ViewGroup mRootView;
...

// 加载布局
this.setContentView(R.layout.activity_main);
...

// 创建一个TextView并添加一些属性
mLabelText = new TextView();
mLabelText.setText("Label").setId("1");

// 获取到视图根布局并创建一个动画效果
mRootView = (ViewGroup) findViewById(R.id.mainLayout);
mFade = new Fade(IN);

// 开始记录视图结构的变化
TransitionManager.beginDelayedTransition(mRootView, mFade);

// 将TextView添加到视图结构中
mRootView.addView(mLabelText);

//当系统开始重绘界面来展示试图变化的时候,框架会自动添加动画

定义场景的生命周期回调方法

场景的生命周期和Activity的生命周期类似,代表了从调用TransitionManager.go()方法开始到动画执行完成的这段时间内被框架监听到的各种状态的改变。在重要的生命周期状态点,框架会调用由TransitionListener定义的回调方法。

转场声明周期回调是非常有用的,例如,需要在场景切换的开始和结束分别记录View属性的时候。不能简单的将场景转换开始时的View的属性值拷贝到场景结束时View的属性值中,因为结束时的视图结构知道整个转场完全结束才会被填充出来。正确的做法是,将该属性值保存到变量中并在转场结束的时候将他赋值到视图结构中。为了能够在转场结束时进行操作,可以实现TransitionListener.onTransitionEnd()方法。
更多的相关信息可以参考TransitionListener的API。

你可能感兴趣的:(android,动画,转场,transitions)