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

前一篇文章中,我们初步了解android.transition框架并开始着手AndroidTransitionExample项目。今天,我们将继续进一步探索如何使用这些类,以及如何从xml文件中加载他们。

为了使用示例工程,我们可以参照前一篇文章中“使用GIT实战”章节。下面是文档给出的一些额外提示。

控制过度效果

让我们来看看如何控制过度效果。首先,我们要进行一下重构。提取goToScene方法,而不是直接调用TransitionManager.go()方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
     goButton.setOnClickListener( new View.OnClickListener() {
         @Override
         public void onClick(View v) {
             //TransitionManager.go(scene); //移除
             goToScene(scene);
         }
     });
...
 
private void goToScene(Scene scene) {
     ChangeBounds changeBounds = new ChangeBounds();
     Fade fadeOut = new Fade(Fade.OUT);
     Fade fadeIn = new Fade(Fade.IN);
     TransitionSet transition = new TransitionSet();
     transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
     transition
             .addTransition(fadeOut)
             .addTransition(changeBounds)
             .addTransition(fadeIn);
     TransitionManager.go(scene, transition);
}

转到“extract method goToScene”:

1
git checkout 6ea37f7

效果是一样的。事实上,如果用AutoTransition效果也一样。但是,这样我们有更多控制,因为这样能把transition集合里的组件绑定到我们的链接上。例如,我们可以改变动画持续的时间:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void goToScene(Scene scene) {
     ChangeBounds changeBounds = new ChangeBounds();
     changeBounds.setDuration( 1000 );
     Fade fadeOut = new Fade(Fade.OUT);
     fadeOut.setDuration( 1000 );
     Fade fadeIn = new Fade(Fade.IN);
     fadeIn.setDuration( 1000 );
     TransitionSet transition = new TransitionSet();
     transition.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
     transition
             .addTransition(fadeOut)
             .addTransition(changeBounds)
             .addTransition(fadeIn);
     TransitionManager.go(scene, transition);
}

转到“slow motion transitions”:

1
git checkout fbcc465

因为某些原因,在开发者选项里的动画控制看起来并不能影响动画过度效果。

上面的代码让我们可以慢速查看动画。我们能控制的不仅仅只有过度的时间而已,还可以尝试添加一个内插程序。经典动画的原则之一说到:角色不能简简单单的就开始移动。他们先要展现出要移动的动作,然后移动,最后在停止之前完成动作(Overshoot)。使用内置的AnticipateOvershootInterpolator能得到想要的效果。注意:我们放慢了边缘动画的变动效果,所以很容易看到效果。

1
2
3
4
ChangeBounds changeBounds = new ChangeBounds();
changeBounds.setInterpolator( new AnticipateOvershootInterpolator());
changeBounds.setDuration( 2000 );
Fade fadeOut = new Fade(Fade.OUT);

转到“use AnticipateOvershootInterpolator”:

1
git checkout 1de57f0

在过度到第二场景后,如果你试着按下“执行转换按钮”会发现并没有什么发生。这是因为,唯一绑定OnClickListener(点击监听)的按钮在第一个layout里。要使第二个场景的按钮正常工作,我们需要另外加载不同场景的界面。

1
2
3
4
5
6
7
8
View rootView = inflater.inflate(R.layout.fragment_transition_scene_1,
         container, false );
/*final Scene scene = Scene.getSceneForLayout(container,
         R.layout.fragment_transition_scene_2, getActivity());*/ //移除
View secondView = inflater.inflate(R.layout.fragment_transition_scene_2,
         container, false );
final Scene scene = new Scene(container, (ViewGroup)secondView);
Button goButton = (Button)rootView.findViewById(R.id.goButton);

现在,我们有了第二视图,可以开启第二个按钮:

1
2
3
4
5
6
7
8
final Scene originalScene = new Scene(container, (ViewGroup)rootView);
Button goBackButton = (Button)secondView.findViewById(R.id.goButton);
goBackButton.setOnClickListener( new View.OnClickListener() {
     @Override
     public void onClick(View v) {
         goToScene(originalScene);
     }
});

最终效果如下图所示:

transition_07

转到“add the return transition”:

1
git checkout 9871bfa

用XML实现过度

到现在为止,我们看了在代码中使用转换框架。当然,也可以通过XML实现。KitK介绍了全新的资源文件夹过度方法,这样的文件夹保存了定义转换,甚至是场景映射的XML文件。

例如,使用XML来定义自定义的转换会这样写(使用slow_auto_transition.xml):

1
2
3
4
5
6
7
8
9
10
11
12
13
< transitionSet
     xmlns:android = "http://schemas.android.com/apk/res/android"
     android:transitionOrdering = "sequential" >
     < fade
         android:fadingMode = "fade_out"
         android:duration = "1000" />
     < changeBounds
         android:duration = "2000"
         android:interpolator = "@android:interpolator/anticipate_overshoot" />
     < fade
         android:fadingMode = "fade_in"
         android:duration = "1000" />
</ transitionSet >

使用XML文件能简化我们goToScene方法:

1
2
3
4
5
6
private void goToScene(Scene scene) {
   TransitionInflater inflater = TransitionInflater.from(getActivity());
   Transition transition
       = inflater.inflateTransition(R.transition.slow_auto_transition);
   TransitionManager.go(scene, transition);
}

现在运行这个项目,结果和之前的是完全相同的。

转到“inflate the transition from the XML file”:

1
git checkout c2a25d4

使用XML进行过度管理

正如上文提及到的那样,可以通过XML文件增加一个完整的transition管理实例。它定义了从一个场景到另一个场景的转换。我们最后对工作做一点改变。下面是transition_manager.xml文件:

1
2
3
4
5
6
7
8
9
10
< transitionManager
     xmlns:android = "http://schemas.android.com/apk/res/android" >
     < transition
         android:fromScene = "@layout/fragment_transition_scene_1"
         android:toScene = "@layout/fragment_transition_scene_2"
         android:transition = "@transition/slow_auto_transition" />
     < transition
         android:fromScene = "@layout/fragment_transition_scene_1"
         android:toScene = "@layout/fragment_transition_scene_2"
         android:transition = "@transition/slow_auto_transition" />

同样我们也修改一下layout,以便不用再在代码中修改button的链接方式:在第一层layout中为id为goButton的按钮添加android:onClick="goToScene2"函数。同样,在第二层layout中添加android:onClick="goToScene1"

1
2
3
4
5
6
< Button
     android:id = "@+id/goButton"
     android:text = "@string/button_go"
     android:layout_width = "wrap_content"
     android:layout_height = "wrap_content"
     android:onClick = "goToScene2" />

我们会把大部分的代码放进TransistionActivity中,而TransitionFragment只用来加载视图:

1
2
3
4
5
6
public View onCreateView(LayoutInflater inflater, ViewGroup container,
         Bundle savedInstanceState) {
     View rootView = inflater.inflate(
                         R.layout.fragment_transition_scene_1, container, false );
     return rootView;
}

TransitionActivity中添加实例变量:

1
2
3
private TransitionManager mTransitionManager;
private Scene mScene1;
private Scene mScene2;

TransitionActivityonCreate函数结束的地方增加下面的代码:

1
2
3
4
5
6
7
8
ViewGroup container = (ViewGroup)findViewById(R.id.container);
TransitionInflater transitionInflater = TransitionInflater.from( this );
mTransitionManager = transitionInflater.inflateTransitionManager(
                         R.transition.transition_manager, container);
mScene1 = Scene.getSceneForLayout(container,
                         R.layout.fragment_transition_scene_1, this );
mScene2 = Scene.getSceneForLayout(container,
                         R.layout.fragment_transition_scene_2, this );

结束的时候,把下面两个函数加到TransitionActivity类:

1
2
3
4
5
6
7
public void goToScene1(View view) {
     mTransitionManager.transitionTo(mScene1);
}
 
public void goToScene2(View view) {
     mTransitionManager.transitionTo(mScene2);
}

最后可以得到相同的效果。

转到“load the transition manager from the XML file”:

1
2
3
git checkout cc40873
或者
git checkout master

尽情享受Transition功能吧!


原文地址  http://blog.jobbole.com/63330/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值