使用Android.Transition框架创建动画(1)

在Android 4.4(KitKat)中,谷歌添加了很多不错的东西。现在我们来看看android.transition框架。

多年来,android不断改进现有的动画工具供开发者使用。在HoneyComb版本中,提供了很多不错的API用于创建丰富、复杂的动画。在此基础上,KitKat的android.transition让我们可以通过一种更直观的方式定义动画效果。

Scene和Transition

先从Scene和Transition概念说起。Scene定义了界面的当前状态信息,而Transition定义了界面之间的切换。

可以从布局文件中载入Scene定义,示例如下:

其中container在Scene中是一个包含了所有view的ViewGroup。如果是在fragment中,Scene就是传入onCreateView()方法的参数。使用Transition的最简单方式就是使用TransitionManager处理,示例如下:

如果在TransitionManager中不明确需要指定哪个Transition,就会默认使用AutoTransition,这个我们会后面介绍。也可以用inflater载入现有的view来创建Scene,示例如下:

Andorid.Transition实践

我们来看一个更详细的示例,首先从项目主页下载示例代码AndroidTransitionExample。这已经是一个已完成的项目了,所以也可以用git checkout检出代码(以下是详细解释)。

首先新建只包含一个Fragment的项目,这样可以更容易记录一些信息。我们为TransitionFragment新建一个xml布局文件,叫做fragment_transition_scene_1.xml。接着往里面添加一个TextView,然后在TextView下面再添加一个Button,如下:

fragment_transition_scene_1.xml

你一定猜得到,我们接下来还要新建另一个xml布局文件,fragment_transition_scene_2.xml。它和上一个布局文件基本一样,只是把Button移到布局底部。示例如下:

这是两个布局的屏幕截图:

transition_01

transition_02

为了看Transition的效果,我们从第二个布局文件中创建Scene。点击goButton的时候展示Transition的效果。我们先修改一下TransitionFragment.onCreateView()方法的代码,如下:

这是点击goButton的效果:

transition_03

为什么会产生这样的效果呢?因为如果view有相同的ID,就会被当做是同一个view,然后也会被改变(通过改变bounds),也就是说,在Scene切换时,view的位置和大小也会改变,需要注意的是两个布局文件的RelativeLayout也要有相同的ID。

使用GIT实战

如果你对整个例子代码感兴趣的话,也可以利用GIT检出代码。从AndroidTransitionExample复制一份即可,你可以用GUI git客户端列出项目的历史版本,也可以定位到某个具体的提交点检出。

当然,你也可以使用命令行。使用cd命令切换到项目文件夹,然后执行以下命令:

此时,你会得到项目的提交列表,像这样:

以上贴出的对应于simple transition这个提交点,执行以下代码可以把项目设置成这个状态:

执行 git checkout ,你可以跳到任意一个提交点上,下面的插入文字会给出指示操作。

修改布局文件

我们来修改一下第二个布局文件,首先把RelativeLayout换成LinearLayout,然后我们来介绍一个在第一个布局文件中没有出现的view,最后我们重新排布一下这些view,代码如下:

我们目前处于“1e7c5be modified layout for scene 2”提交点,在命令行执行git checkout 1e7c5be就可以切换上去。可以看到,Transition仍然起作用,在第一个Scene里面,不存在的view竟然出现在屏幕上,然后随着Button和TextView的移动而逐渐消失。

我们详细看看AutoTransition,事实证明,它只是TransitionSet的子类,只是它给自己定义了一个执行序列,分别是fading out、changing bounds、fading in。

我们注意到,在第二个Transition中,AutoTransition会改变bounds,目前我们只看到了Button和TextView改变了位置,如果我们改变view的大小会出现什么情况呢?在Button中添加layout_weight属性来看看效果:

现在Button在转变的过程中既改变了位置也改变了大小。

现在切换到“added layout_weight to button”这个点,命令:git checkout 092ebe0。现在再做一些变化效果,在Scene中把Button转变成ImageView

此时切换到“example of transitioning from Button to ImageView”这个点,命令: git checkout 6b4629c。看看从Button变成ImageView的效果:

仔细看你会发现,第一个Button首先被一张切割过的图片替换了,然后逐渐移动到最终的位置,逐渐改变大小。

如果我们改变所有views的嵌套结构,比如在Button外面套一层LinearLayout,那么Bounds就不会改变了。transition manager要求在Scene的布局文件中,同一层级的view要有和之前相同的ID:

此时切换到“example of change bounds not working when changing hierarchy”这个点,命令:git checkout 2b000b3

如果我们在第一个Scene中继续用LinearLayout包含Button,那么还是不行。想让它起作用的话,可以给LinearLayout一个相同的ID。这会得到两种不同的效果。

切换到“restore transition by adding LinearLayout with id”,命令:git checkout 34e0f8f

下一篇我们我们继续研究怎么控制Transition,以及如何从xml文件中载入Transition。

1 收藏 评论

关于作者:chris

新浪微博:@yflai01110111 个人主页 · 我的文章 · 12

可能感兴趣的话题



直接登录
跳到底部
返回顶部