android动画应用场景,使用Transitions API为安卓应用创建动画

1432517528134973.png

为安卓创建动画

虽然移动应用对动画的依赖相当普遍,但在安卓系统中开发者认为创建一个动画的过程一直都是一种挑战。ios早就提供了处理动画的实用工具,而安卓上帮助开发者提高工作效率的解决方案还相对较新。

这些动画工具大大的节省了程序员的时间。 使用这些工具实现 creating a variety of app animations 非常方便。和对不同屏幕应用动画不同,开发者可以使用Transition API制造所谓的“场景动画”,Transition API自动产生过渡效果,而这只是冰山一角。我相信这篇文章所要分享的知识对安卓开发者会非常有用。

Transitions API:是如何工作的?

即使在Android4.0上,也有一个解决动画问题的早期办法:针对ViewGroup的布局动画。但是这个工具不够灵活,开发者无法完全掌控动画的过程。不过从Android 4.4 KitKat开始,有了Transitions API,在兼容包中也有Transitions API,因此可以在几乎所有的安卓设备上使用。(这点我大大的怀疑,也许兼容包中是有Transitions API,但是只是做到不出错,兼容而已,根本没有动画效果,不知道新的兼容包是否有改进)。

在KitKat Transition API中,出现了诸如场景(Scene)、场景过渡(Transition)这样的概念,为了决定root  layout,场景Scene root被引入,场景中的所有变化都发生在Scene root中。同时,场景自身本质上是对ViewGroup的一层封装,描述了自己以及所有View对象的的状态。而过渡(Transition)则是一种这样的机制:读取不同场景之间View属性的变化,从而产生让这种变化看起来平滑的动画。

KitKat中Transition框架的Transition API为创建动画提供了如下特色:组级别的动画:可以将整个View树作为整体动画,你只需指定ViewGroup,它的各个元素就会自动应用动画。

基于Transition的动画

内置动画:内置简单的动画,比如dissolution,darkening,resizing,movement等等。

对资源文件的支持:你可以不必写代码,在资源文件中创建动画。

回调:提供掌控动画过程的所有必要的回调方法。

原文此处有youtube视频

虽然有如此多的优点。但是这个新的api也有一些局限:在那些不在UI线程中工作的View,比如SurfaceView或者TextureView中使用的时候不流畅。

AdapterView,比如ListView,当你需要针对列表中某个单独的元素使用动画的时候。

偶尔会在resize TextView的时候会出现同步的问题:在另一个对象的改变结束的之前,字体会提前出现在下一个场景中。

但是,这些局限都不是很关大局。在实际开发中,需要在SurfaceView中应用动画的类似情况非常少见。

考虑下面Transition框架的动画例子:

通过资源文件创建一个场景:

res/layout/activity_main.xml

android:id="@+id/master_layout">

android:id="@+id/title"

...

android:text="Title"/>

android:id="@+id/scene_root">

res/layout/scene_first.xml

android:id="@+id/scene_container"

android:layout_width="match_parent"

android:layout_height="match_parent" >

android:id="@+id/text_view1

android:text="Text Line 1" />

android:id="@+id/text_view2

android:text="Text Line 2" />

res/layout/scene_second.xml

android:id="@+id/scene_container"

android:layout_width="match_parent"

android:layout_height="match_parent" >

android:id="@+id/text_view2

android:text="Text Line 2" />

android:id="@+id/text_view1

android:text="Text Line 1" />

Scene mFirstScene;

Scene mSecondScene;

// Create the scene root for the scenes in this app

mSceneRoot = (ViewGroup) findViewById(R.id.scene_root);

// Create the scenes

mFirstScene =

Scene.getSceneForLayout(mSceneRoot, R.layout.scene_first, this);

mSecondScene =

Scene.getSceneForLayout(mSceneRoot, R.layout.scene_second, this);

通过代码创建场景:// Obtain the scene root element

mSceneRoot = (ViewGroup) findViewById(R.id.scene_root);

// Obtain the view hierarchy to add as a child of

// the scene root when this scene is entered

mViewHierarchy = (ViewGroup)findViewById(R.id.scene_conteiner);

// Create a scene

Scene scene = new Scene(mSceneRoot, mViewHierarchy);

通过资源文件创建Transition:

res/transition/fade_transition.xml

Transition mFadeTransition =

TransitionInflater.from(this).

inflateTransition(R.transition.fade_transition);

也可以完全通过代码创建:Transition mFadeTransition = new Fade();

你还可以创建整个动画集。比如:move,resize,darken无缝的结合在一起:

在资源文件中:

android:transitionOrdering="sequential">

在代码中:TransitionSet set = new TransitionSet();

set.addTransition(new Fade())

.addTransition(new ChangeBounds())

.addTransition(new AutoTransition());

如果需要,还可以将动画应用到某个View对象,而不是整个场景:

只需一行代码就可以创建Transition Manager。需要将所有的场景和Transition都写在一个地方。Transition Manager提高了工作速度和掌控动画过程的效率。

res/transition/transition_manager.xml

app:fromScene="@layout/scene_reg1"

app:toScene="@layout/scene_reg2"

app:transition="@transition/trans_reg1_to_reg2" />

app:fromScene="@layout/scene_reg2"

app:toScene="@layout/scene_reg3"

app:transition="@transition/trans_reg2_to_reg3" />

...

如何运行场景? 简单!

使用自定义的Transition:mTransitionManager.transitionTo(scene);

或者TransitionManager.go(scene, fadeTransition);

使用默认的Transition:TransitionManager.go(scene);

或者根本没有Transition:scene.enter();

你也可以无需创建场景就使用Transition:

res/layout/activity_main.xml

android:id="@+id/mainLayout"

android:layout_width="match_parent"

android:layout_height="match_parent" >

android:id="@+id/inputText"

android:layout_alignParentLeft="true"

android:layout_alignParentTop="true"

android:layout_width="match_parent"

android:layout_height="wrap_content" />

...

MainActivity.javaprivate TextView mLabelText;

private Fade mFade;

private ViewGroup mRootView;

// Load the layout

setContentView(R.layout.activity_main);

// Create a new TextView and set some View properties

mLabelText = new TextView();

mLabelText.setText("Label").setId("1");

// Get the root view and create a transition

mRootView = (ViewGroup) findViewById(R.id.mainLayout);

mFade = new Fade(IN);

// Start recording changes to the view hierarchy

TransitionManager.beginDelayedTransition(mRootView, mFade);

// Add the new TextView to the view hierarchy

mRootView.addView(mLabelText);

// When the system redraws the screen to show this update,

// the framework will animate the addition as a fade in

使用TransitionListener的接口,你可以控制每个动画元素的执行过程:public static interface TransitionListener {

void onTransitionStart(Transition transition);

void onTransitionEnd(Transition transition);

void onTransitionCancel(Transition transition);

void onTransitionPause(Transition transition);

void onTransitionResume(Transition transition);

}

创建自己的动画,比如你可以改变View的背景颜色:

原文此处有youtube视频public class ChangeColor extends Transition {

private static final String PROPNAME_BACKGROUND =

"customtransition:change_color:background";

private void captureValues(TransitionValues values) {

values.values.put(PROPNAME_BACKGROUND, values.view.getBackground());

}

@Override

public void captureStartValues(TransitionValues transitionValues) {

captureValues(transitionValues);

}

@Override

public void captureEndValues(TransitionValues transitionValues) {

captureValues(transitionValues);

}

@Override

public Animator createAnimator(ViewGroup sceneRoot,

TransitionValues startValues,

TransitionValues endValues) {

if (null == startValues || null == endValues) {

return null;

}

final View view = endValues.view;

Drawable startBackground =

(Drawable) startValues.values.get(PROPNAME_BACKGROUND);

Drawable endBackground =

(Drawable) endValues.values.get(PROPNAME_BACKGROUND);

ColorDrawable startColor = (ColorDrawable) startBackground;

ColorDrawable endColor = (ColorDrawable) endBackground;

if (startColor.getColor() == endColor.getColor()) {

return null;

}

ValueAnimator animator = ValueAnimator.ofObject(new ArgbEvaluator(),

startColor.getColor(), endColor.getColor());

animator

.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

Object value = animation.getAnimatedValue();

if (null != value) {

view.setBackgroundColor((Integer) value);

}

}

});

return animator;

}

}

自动产生中间值,这就是为什么我们的例子中颜色逐渐从红色变到蓝色。这个方法打开了创建多种自定义动画与过渡的可能性:只有想不到,没有做不到。

为什么我们要关心Transition?

关于创建动画的快速与简便请了解development of mobile apps。Azoft团队对Transitions API非常热情,我们已经在项目中使用了这个方法。使用Scene创建动画节省了很多时间和精力,这对开发者和急于看到结果的客户来说都是好事。

告诉我们关于你为安卓创建动画的经历。你们使用Transitions API吗?除此之外你们还使用什么工具来为移动应用创建动画?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值