AndroidL动画-ActivityOptionsCompat使用

引用参考:Material Designer的低版本兼容实现(五)—— ActivityOptionsCompat

以下所有的效果都建立在Build.VERSION.SDK_INT >= 16的基础上,也就是June 2012: Android 4.1android系统。

方法

  • ActivityOptionsCompat.makeCustomAnimation(context, enterResId, exitResId)

其中资源id为animxml资源。

使用实例:

1
2
3
4
5
6
7
8

//让新的Activity从一个小的范围扩大到全屏

ActivityOptionsCompat options =
ActivityOptionsCompat.makeCustomAnimation(this,
R.anim.slide_bottom_in, R.anim.slide_bottom_out);
Intent intent = new Intent(this,DetailActivity.class);
ActivityCompat.startActivity(this, intent, options.toBundle());

注意:使用ActivityCompat.startActivity()进行跳转。
跟传统的比较使用,感觉传统的更加简单,方便。

1
2
3
Intent intent = new Intent(this,DetailActivity.class);  
startActivity(intent);
overridePendingTransition(R.anim.slide_bottom_in, android.R.anim.fade_out);

  • ActivityOptionsCompat.makeScaleUpAnimation(source, startX, startY, startWidth, startHeight)

    实现新的Activity从某个固定的坐标以某个大小扩大至全屏
    使用实例:

    1
    2
    3
    4
    5
    6
    7
    //让新的Activity从一个小的范围扩大到全屏
    ActivityOptionsCompat options =
    ActivityOptionsCompat.makeScaleUpAnimation(view, //The View that the new activity is animating from
    (int)view.getWidth()/2, (int)view.getHeight()/2, //拉伸开始的坐标
    0, 0);//拉伸开始的区域大小,这里用(0,0)表示从无到全屏
    Intent intent = new Intent(this,DetailActivity.class);
    ActivityCompat.startActivity(this, intent, options.toBundle());

效果:
enter image description here

  • ActivityOptionsCompat.makeSceneTransitionAnimation(activity, sharedElement, sharedElementName)

    当你需要当前界面中的某个元素和新界面中的元素有关时.
    两个不同Activity的中的布局元素设定同样的一个android:transitionName
    还需要一个标志来告诉Window执行动画,因为这个只是在5.x上有效。非5.x的版本话将导致直接奔溃,需要对版本进行判断。

该标志为:

1
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

注意

both your entering and exiting activities。即要在两个关联的activity进行设置。

实现效果:enter image description here
步骤:

首先有两个activityA,activityB,其中点击actvityA的recyclerview的item进行跳转到ActivityB

  1. 分别在activityA,activityBsetContentView()前设置
1
etWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

如果不添加这句话的话,将导致A-B-C,在C按下后退,则返回到A.

  • 在A中的item设置跳转逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Intent intent = ReViewsActivity.startReViewsActivity(getContext(), subjectsInfo.getId());
((ViewGroup) vh.getBinding().ivMovie.getParent()).setTransitionGroup(false);//1
ByteArrayOutputStream stream = new ByteArrayOutputStream();
((BitmapDrawable) vh.getBinding().ivMovie.getDrawable()).getBitmap().compress(Bitmap.CompressFormat.PNG, 100, stream);
intent.putExtra("image", stream.toByteArray());
ActivityOptions options;
try {
options = ActivityOptions.makeSceneTransitionAnimation((Activity) getContext(), vh.getBinding().ivMovie, "image");
} catch (NullPointerException e) {
return;
}
if (options == null) {
Log.e("sharedelementanimation", "Options is null. Something broke. Good luck!");
} else {
getContext().startActivity(intent, options.toBundle());
}

这里分为以下几步:

  • set the transition group for the parent container view to false
  • 将当前的ImageviewDrawable资源转化为bitmap
  • 使用intent传递stream.toByteArray()byte[]数组
  • create ActivityOptions with a scene transition animation for our imageview and start the next activity
  • 最后得到bundle进行传递
  1. 接下来设置AcitvityB,得到bitmap并进行显示。
1
2
3
4
5
6
7
8
9
setContentView()
byte[] byteArray = getIntent().getByteArrayExtra("image");
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
mImageView.setImageBitmap(bitmap);
@Override
public void onBackPressed() {
super.onBackPressed();
finishAfterTransition();
}
  1. 最终要的一步:关联两个Activity中imageView

    使用android:transitionName="imageview",分别在两个actlayout进行对应的设置。

详细查看:
ANDROID L——Material Design详解(动画篇)
Getting Started with Android L Animations

  • ActivityOptionsCompat.makeSceneTransitionAnimation((Activity arg0, Pair… arg1)

    这个方法用于多个元素和新的Activity相关的情况,注意下第二个参数Pair这个键值对后面有…,标明是可以传入多个Pair对象的。

  • ActivityOptionsCompat.makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY)

    这个方法可以用于4.x上,是将一个小块的Bitmpat进行拉伸的动画。

此类动画效果的兼容:

用开源项目ActivityOptionsICS让ActivityOptions的动画实现兼容
项目地址:ActivityOptionsICS