Android L带来了许多新特性,其中就包括了大量的动画效果,你可以在自己的应用中使用。本文中我将详解这些动画和如何在应用中使用。本文中的所有代码可以在github上找到。
波纹和强调
现在安卓支持少量的预定义样式属性,不过只限于应用特定部分例如状态栏、导航栏。新系统允许我们采用简单的方式即可获得两种非常简洁、有用的动画:波纹和被强调的UI组件。波纹是一种给予用户在UI上动作极好的回应效果,并且可以自定义波纹的颜色,只需要给colorControlHighlight 属性设置色值。
1 |
<item name="android:colorControlHighlight">#0000AA</item> |
一样简单,很多UI组件像复选框都可以使用styles文件夹中的colorAccent 属性来设置符合你应用主题的颜色,而不必使用不同的图片和状态选择器。
1 |
<item name="android:colorAccent">#00FF00</item> |
圆形显示
安卓中一件常见工作就是改变屏幕上某一元素的可见性。现在开发者又多了一个选择可以让这项工作完成的更加漂亮:圆形显示。使用ViewAnimationUtil.createCircularReveal方法然后通过动画监听在合适的时间改变View的可见性。这有两个相似的方法用来让View可见或者消失。注意显示方法有一个持续时间的设置,以便完成动画的显示,隐藏动画执行的更快一点。getX()和getY()方法返回图片所在X、Y轴的中心点的坐标,getRadius()方法就是返回View的宽度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
private void hideImageCircular() { int x = getX(); int y = getY(); int radius = getRadius(); ValueAnimator anim = ViewAnimationUtils.createCircularReveal(mImageView, x, y, radius, 0); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); mImageView.setVisibility( View.INVISIBLE ); } }); anim.start(); } private void revealImageCircular() { int x = getX(); int y = getY(); int radius = getRadius(); ValueAnimator anim = ViewAnimationUtils.createCircularReveal(mImageView, x, y, 0, radius); anim.setDuration( 1000 ); anim.addListener( new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); mImageView.setVisibility( View.VISIBLE ); } }); anim.start(); } |
Activity转场动画
除了前述几种动画,android L还增加了一些activity的过渡动画——爆炸、滑动、淡入淡出,让应用更加平滑。使用这些动画,你必须在进入和退出activity都要求使用这些内容转场特效,并且在setOncontent()方法之前。
1 |
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); |
也支持通过样式设置转换动画,我将详解如何在activity中通过样式设置专场效果。使用getWindow().setExitTransition( Transition ) 和getWindow().setEnterTransition( Transition ) 方法告诉activity当打开和关闭时如何执行。使用迸发动画,从MainActivity和ListFragment 到第二个activity的代码可以这样写:
1 2 3 4 |
ListFragment: getActivity().getWindow().setExitTransition( new Explode() ); intent = new Intent( getActivity(), ExplodeAnimationActivity.class ); startActivity( intent ); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
ExplodeAnimationActivity: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); getWindow().setEnterTransition( new Explode() ); getWindow().setExitTransition( new Explode() ); setContentView(R.layout.activity_explode_animation); } @Override public void onBackPressed() { super.onBackPressed(); finishAfterTransition(); } |
注意onBackPressed()方法——这很重要。因为它让操作系统知道在关闭第二个activity之前要完成动画的执行。使用这些简单的代码,我们就拥有了三种activity专场动画。
虽然我没有用到这个非常有用的工具,但是应当引起注意的是专场动画监听——Transition.TransitionListener。使用监听可以在进入和退出动画生命周期中的特定点执行一些操作,给你更多让应用如何表现的控制权。为了防止内容泄漏,需要在Ondestory()方法中移除监听。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
getWindow().getEnterTransition().addListener( new Transition.TransitionListener { @Override public void onTransitionStart(Transition transition) { } @Override public void onTransitionEnd(Transition transition) { } @Override public void onTransitionCancel(Transition transition) { } @Override public void onTransitionPause(Transition transition) { } @Override public void onTransitionResume(Transition transition) { } }); |
Activity专场动画之元素共享
除了标准的过渡动画,现在支持在两个activity过渡动画过程中共享元素。第一件要做的就是设置activity,使用内容转场动画并且允许覆盖转场动画。可以通过样式来设置:
1 2 3 |
<item name="android:windowContentTransitions">true</item> <item name="android:windowAllowEnterTransitionOverlap">true</item> <item name="android:windowAllowExitTransitionOverlap">true</item> |
元素共享动画也可以在代码中设置,此例中,我将使用样式来完成:
1 2 |
<item name="android:windowSharedElementEnterTransition">@transition/changebounds</item> <item name="android:windowSharedElementExitTransition">@transition/changebounds</item> |
Changebounds转场动画被定义以xml文件的形式存放在资源文件中。注意,我增加了两位两个属性:时长和插值器,让动画更有趣。
1 2 3 |