参考https://www.jianshu.com/p/0af52be90ae6
效果预览
Explode | Slide | Fade |
---|---|---|
|
|
|
在开始讲解之前我们先做一些约定,虽然下面的约定是针对activity的,但是在Fragment中也是一样的约定。
A和B分别是两个Activity,假设activity A 调用activity B。将A代表调用Activity ,B代表被调用Activity。
Activity transition API围绕退出(exit),进入(enter),返回(return)和再次进入(reenter)四种transition。按照上面对A和B的约定,我这样描述这一过程。
Activity A的退出变换(exit transition)决定了在A调用B的时候,A中的View是如何播放动画的。
Activity B的进入变换(enter transition)决定了在A调用B的时候,B中的View是如何播放动画的。
Activity B的返回变换(return transition)决定了在B返回A的时候,B中的View是如何播放动画的。
Activity A的再次进入变换(reenter transition)决定了在B返回A的时候,A中的View是如何播放动画的。
使用前的设置
在调用与被调用的activity中,通过设定Window.FEATURE_ACTIVITY_TRANSITIONS
和 Window.FEATURE_CONTENT_TRANSITIONS 来启用transition api ,可以通过代码也可以通过设置主题来启用:
代码方式,在setContentView之前调用:
//设置允许通过ActivityOptions.makeSceneTransitionAnimation发送或者接收Bundle
getWindow().requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS);
//设置使用TransitionManager进行动画,不设置的话系统会使用一个默认的TransitionManager
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
主题xml
- true
使用步骤
1.Transition主要有退出(exit),进入(enter),返回(return),再次进入(reenter)四种变换,我们可以通过getWindow()然后进行设置,如下所示:
getWindow().setExitTransition(new Fade());//传入新建的变换
getWindow().setReenterTransition(new Explode());
getWindow().setEnterTransition(new Slide());
getWindow().setReturnTransition(new Fade());
假设我们通过ActivityA启动ActivityB,则这四种变化分别是指 :
1.ActivityA的退出变换(ExitTransition)决定了A调用B的时候,A中的View是如何播放动画的;
2.ActivityB的进入变换(EnterTransition)决定了A调用B的时候,B中的View是如何播放动画的;
3.ActivityB的返回变换(ReturnTransition)决定了在B返回A的时候,B中的View是如何播放动画的;
4.ActivityA的再次进入变换(ReenterTransition)决定了在B返回A的时候,A中的View是如何播放动画的。
分别在调用与被调用的activity中设置exit 和enter transition。Material主题默认会将exit的transition设置成null而enter的transition设置成Fade .如果reenter 或者 return transition没有明确设置,则将用exit 和enter的transition替代。
在主题中设置默认变换
在res下新建transition文件夹,在里面新建explode.xml
2. 开始一个activity的内容变换:
需要调用startActivity(Context, Bundle)方法,将下面的bundle作为第二个参数:
Intent mIntent = new Intent();
mIntent.setClass(this, TransitionActivity.class);
mIntent.putExtra("transition", "explode");
Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(activity, pairs).toBundle();
startActivity(mIntent,bundle);
其中pairs参数是一个数组:Pair
,该数组列出了你想在activity之间共享的view和view的名称。别忘了给你的共享元素加上一个唯一的名称,否则transition可能不会有正确的结果。
3.共享元素变换
Transition框架不仅可以实现在内容变换时的动画效果,同时还可以设置在两个界面中的共享元素变换。
在程序中使用共享元素的动画效果非常简单,只需要分别为两个需要共享的元素设置相同的transitionName,并在ActivityOptions.makeSceneTransitionAnimation中将需要共享的元素作为参数传递过去即可。
例如我们需要共享ActivityA和ActivityB中的两个Image图片,则只需要分别为两个Image在布局文件中设置相同的transitionName:
//在另一个imageview中设置一样的transitionName
需要注意两个transitionName一定要命名相同,这样系统才能找到共享元素。
如果我们只需要设置一个共享元素,那么在ActivityA中使用如下代码进行跳转:
Intent intent = new Intent(MainActivityA.this, MainActivityB.class);
ActivityOptions option = ActivityOptions
.makeSceneTransitionAnimation(MainActivityA.this,imageView,"share_image");
startActivity(intent, option.toBundle());
我们发现和之前内容变换使用的是相同的方法,只是在参数上多了共享的view和共享的变换名称,即之前设置的transitionName;
如果我们需要多个共享的元素,可以通过Pair.create()进行创建,如下所示:
ActivityOptions option = ActivityOptions.makeSceneTransitionAnimation(MainActivityA.this,
Pair.create(imageView, "share_image"),
Pair.create(button, "share_button"));
需要注意的是Pair.create()中的两个参数,第一个参数为需要共享的View,第二个参数为共享的名称,即各自的transitionName;在使用的时候发现对于不同的view如Button,ImageView都需要将其强转为View,才能作为Pair.create()的第一个参数。
4.分别在调用与被调用的activity中设置exit 和enter 共享元素的transition。Material主题默认会将exit的共享元素transition设置成null而enter的共享元素transition设置成@android:transition/move.如果reenter 或者 return transition没有明确设置,则将用exit 和enter的共享元素transition替代。
5.在代码中触发通过finishAfterTransition()方法触发返回动画,而不是调用finish()方法。
6.默认情况下,material主题的应用中enter/return的content transition会在exit/reenter的content transitions结束之前开始播放(只是稍微早于),这样会看起来更加连贯。如果你想明确屏蔽这种行为,可以调用setWindowAllowEnterTransitionOverlap() 和 setWindowAllowReturnTransitionOverlap()方法。
Fragment Transition
如果你想在Fragment中使用transition,除了一小部分区别之外和activity大体一致:
1.Content的exit, enter, reenter, 和return transition需要调用fragment的相应方法来设置,或者通过fragment的xml属性来设置。
2.共享元素的enter和return transition也n需要调用fragment的相应方法来设置,或者通过fragment的xml属性来设置。
3.虽然在activity中transition是被startActivity()和finishAfterTransition()触发的,但是Fragment的transition却是在其被FragmentTransaction执行下列动作的时候自动发生的。added, removed, attached, detached, shown, ,hidden。
4.在Fragment commit之前,共享元素需要通过调用addSharedElement(View, String) 方法来成为FragmentTransaction的一部分。
Slide常用属性(另两种变换类似)
Slide exitTransition = new Slide(Gravity.TOP);//设置从哪个方向进入
exitTransition.setDuration(500);//设置时间