虽然我没有用到这个非常有用的工具,但是应当引起注意的是专场动画监听——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 4 5 | changebounds.xml:
< changeBounds
xmlns:android = "http://schemas.android.com/apk/res/android"
android:duration = "1000"
android:interpolator = "<a href=" http://www.jobbole.com/members/android/" rel = "nofollow" >@android</ a >:interpolator/bounce" />
|
下一步就是,确定在两个activity的布局文件中都使用实现Comparable接口的View类型(此例中使用ImageView),并且他们的viewName 属性值必须相同。在第一个activity中具有共享元素的View是这样的: 1 2 3 4 5 | < ImageView
android:id = "@+id/image"
android:viewName = "image"
android:layout_width = "match_parent"
android:layout_height = "250dp" />
|
第二个activity中的是这样的: 1 2 3 4 5 6 | < ImageView
android:id = "@+id/image"
android:layout_alignParentBottom = "true"
android:viewName = "image"
android:layout_width = "match_parent"
android:layout_height = "250dp" />
|
既然所有的xml设置都准备好了,我们可以开始在执行动画的activity中写代码了。在第一个activity中我们设置父类容器视图setTransitionGroup为false,然后获取我们想要共享元素的ImageView的drawable,把它转变为字节流对象放到intent的bundle中。然后,为ImageView使用场景动画转换创建ActivityOptions 对象,开启下一个activity。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | Intent intent = new Intent( this , SharedElementSecondAnimationActivity. class );
((ViewGroup) mImageView.getParent()).setTransitionGroup( false );
ByteArrayOutputStream stream = new ByteArrayOutputStream();
( (BitmapDrawable) mImageView.getDrawable() ).getBitmap().compress(Bitmap.CompressFormat.PNG, 100 , stream);
intent.putExtra( "image" , stream.toByteArray() );
ActivityOptions options;
try {
options = ActivityOptions.makeSceneTransitionAnimation( this , mImageView, "image" );
} catch ( NullPointerException e ) {
Log.e( "SharedElementAnimationChangeBoundsActivity" , "Did you set your ViewNames in the layout file?" );
return ;
}
if ( options == null ) {
Log.e( "sharedelementanimation" , "Options is null. Something broke. Good luck!" );
} else {
startActivity(intent, options.toBundle());
}
|
在第二个activity中,从Intent的bundle中读取字节流并解码为bitmap对象,然后把它设置到Imageview上。第二个activity也重写了onBackPressed()方法,为了当返回键按下的时候执行退出动画。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout.activity_shared_element_second_animation);
mImageView = (ImageView) findViewById( R.id.image );
byte [] byteArray = getIntent().getByteArrayExtra( "image" );
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0 , byteArray.length);
mImageView.setImageBitmap(bitmap);
}
@Override
public void onBackPressed() {
super .onBackPressed();
finishAfterTransition();
}
|
基于以上这些我们完成了共享元素转换动画,在第二个activity中共享元素被移动到新的位置,并且有一个回弹效果。 
这几个动画的例子仅是android L的冰山一角,而且没有涉及Kit Kat中引入的场景动画。我希望这篇教程帮助其他开发者学习到新的东西,使用动画让应用不但好看而且有趣。 |