自定义转场动画

学习5.x的动画后,由于主流手机还在4.x中徘徊。所以不得不进行适配兼容。在兼容动画中用得最常的是转场动画。也就是跳转动画:A->start->B/B->finish->A。到底怎么自定义设置呢?

通过查看兼容动画的源码发现如下代码块:

  • 进入动画(start):
1
2
3
mSceneRoot.setAlpha(255);
currActivity.startActivity(intent);
currActivity.overridePendingTransition(0, 0);
  • 后退动画(finish):
1
2
3
4
5
protected void exitAnimsEnd() {
mSceneRoot.setAlpha(0);
mActivity.finish();
mActivity.overridePendingTransition(0, 0);
}

两段代码关键点如下:

  • mActivity.overridePendingTransition(0, 0);

    用来禁止默认的跳转动画

  • mSceneRoot的获取

    这个是整个Activity根view,如何进行获取?
    通过晚上的搜索,推荐的方式为:

1
currActivity.getWindow().getDecorView().findViewById(android.R.id.content);

但通过实战发现,并不能真正得到rootview,底部总是有一部分被遗漏了。通过以下可解决:

1
((ViewGroup) destActivity.getWindow().getDecorView()).getChildAt(0);

接着大胆的进行设置进入和退出的动画,其步骤为:

  1. A->startActvity()+overridePendingTransition(0,0);->B
  2. B->动画准备->setContentView()布局->执行动画
  3. B->onBackPressed()->执行动画->动画结束:finish()+overridePendingTransition(0,0);

通过实战发现:进入动画可以很平滑的过渡,而退出动画则总是在动画完成后一闪而过的效果,体验很不好。

于是再看兼容库:发现别人设置了主题:透明

1
2
3
4
<style name="TranslucentTheme" parent="AppTheme">
<!--背景透明-->
<item name="android:windowIsTranslucent">true</item>
</style>

但还是一样死活不成功,话说是各种手机对windowIsTranslucent的兼容不好,再看其他的兼容库: AnimeWallpaper,发现如下设置:

1
2
3
4
5
6
7
<style name="TranslucentTheme" parent="AppTheme">
<!--背景透明-->
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<!--无进入动画-->
<item name="android:windowAnimationStyle">@null</item>
</style>

终于完美解决。原理应该是当B变成透明后,那么一闪而过的效果由于是透明,导致用户感觉不多。

实战代码:

  • 进入动画:
1
2
3
4
5
6
7
8
9
10
11
12
public void customTransition(final SubjectsInfo subjectsInfo){
final Activity activity=(Activity) getContext();
ViewGroup viewGroup = (ViewGroup) ((ViewGroup) activity.getWindow().getDecorView()).getChildAt(0);
viewGroup.animate().alpha(0.5f).setDuration(1000).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
//跳转
activity.startActivity(ReViewsActivity.startReViewsActivity(getContext(), subjectsInfo.getId()));
activity.overridePendingTransition(0,0);
}
});
}
  • 退出动画:
1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public void onBackPressed() {
ViewGroup viewGroup = (ViewGroup) ((ViewGroup) this
.findViewById(android.R.id.content)).getChildAt(0);
viewGroup.animate().alpha(0f).setDuration(1000).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
ReViewsActivity.this.finish();
ReViewsActivity.this.overridePendingTransition(0,0);
}
});
}

执行重写:onBackPressed并不需要super.