1. 场景过渡动画
场景过渡动画是指以动画的形式实现View
两个场景的切换,场景过渡动画中有两个特别关键概念:Scene
(场景),Transition
(过渡)。
Scene
,代表一个场景Transition
,用来设置过渡动画效果用的
系统给提供了一些Transition
动画效果。
系统Transition | 说明 |
---|---|
ChangeBounds | 检测view的位置边界创建移动和缩放动画 |
ChangeTransform | 检测view的scale和rotation创建缩放和旋转动画 |
ChangeClipBounds | 检测view的剪切区域的位置边界 |
ChangeImageTransform | 检测ImageView的尺寸,位置以及ScaleType |
Fade | 根据View的visibility状态的的不同创建淡入淡出动画 |
Slide | 根据View的visibility状态的的不同创建滑动动画 |
Explode | 根据View的visibility状态的的不同创建爆炸动画 |
AutoTransition | 默认动画,ChangeBounds、Fade动画的集合 |
2. TransitionManager.go场景动画
TransitionManager.go()
实现场景动画,需要Scene
和Transition
。Scene
通过getSceneForLayout(ViewGroup sceneRoot, int layoutId, Context context)
方法获得,需要三个参数,其中sceneRoot
是场景所在的View
, layoutId
是布局文件。
if (mChange) {
Scene scene = Scene.getSceneForLayout(mContainer, R.layout.layout_scene_init, this)
TransitionManager.go(scene, new ChangeBounds());
} else {
Scene scene = Scene.getSceneForLayout(mContainer, R.layout.layout_scene_change_bounds, this);
TransitionManager.go(scene, new ChangeBounds());
}
mChange = !mChange;
layout_scene_init.xml
文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="150dp">
<ImageView
android:id="@+id/iv_link"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="15dp"
android:src="@drawable/icon_link"
android:transitionName="sharedView1"/>
<ImageView
android:id="@+id/iv_qq"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="15dp"
android:layout_alignParentRight="true"
android:src="@drawable/icon_qq"
android:transitionName="sharedView2"/>
<ImageView
android:id="@+id/iv_pyq"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="15dp"
android:layout_alignParentBottom="true"
android:src="@drawable/icon_pyq"
android:transitionName="sharedView3"/>
<ImageView
android:id="@+id/iv_wx"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="15dp"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:src="@drawable/icon_wx"
android:transitionName="sharedView3"/>
</RelativeLayout>
layout_scene_change_bounds.xml
文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="150dp">
<ImageView
android:id="@+id/iv_wx"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="15dp"
android:src="@drawable/icon_wx"/>
<ImageView
android:id="@+id/iv_pyq"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="15dp"
android:layout_alignParentRight="true"
android:src="@drawable/icon_pyq"/>
<ImageView
android:id="@+id/iv_qq"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="15dp"
android:layout_alignParentBottom="true"
android:src="@drawable/icon_qq"/>
<ImageView
android:id="@+id/iv_link"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="15dp"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:src="@drawable/icon_link"/>
</RelativeLayout>
效果如下
3. TransitionManager.beginDelayedTransition场景动画
TransitionManager.beginDelayedTransition()
实现场景动画,需要sceneRoot
和Transition
。
TransitionManager.beginDelayedTransition(ViewGroup, Transition)
实现场景动画。
ChangeTransform
,修改缩放。
效果如下TransitionManager.beginDelayedTransition(mContainer, new ChangeTransform()); if (mChange) { mImageView.setScaleX(1); mImageView.setScaleY(1); } else { mImageView.setScaleX(0.5f); mImageView.setScaleY(0.5f); } mChange = !mChange;
ChangeClipBounds
,裁剪位置
效果如下TransitionManager.beginDelayedTransition(mContainer, new ChangeClipBounds()); if (mChange) { mImageView.setClipBounds(null); } else { mImageView.setClipBounds(new Rect(10, 10, 110, 110)); } mChange = !mChange;
ChangeImageTransform
,修改ImageView
的ScaleTyepe
效果如下TransitionManager.beginDelayedTransition(mContainer, new ChangeImageTransform()); if (mChange) { mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER); } else { mImageView.setScaleType(ImageView.ScaleType.CENTER); } mChange = !mChange;
Fade
、Slide
和Explode
,修改visibility
。利用TransitionSet
实现多种动画,需要指定Target
,Slide
可指定方向。
效果如下TransitionManager.beginDelayedTransition(mContainer, new TransitionSet() .addTransition(new Fade() .addTarget(R.id.iv_link)) .addTransition(new Slide(Gravity.TOP) .addTarget(R.id.iv_qq)) .addTransition(new Explode() .addTarget(R.id.iv_pyq) .addTarget(R.id.iv_wx))); if (!mChange) { mIvLink.setVisibility(View.GONE); mIvQQ.setVisibility(View.GONE); mIvPyq.setVisibility(View.GONE); mIvWX.setVisibility(View.GONE); } else { mIvLink.setVisibility(View.VISIBLE); mIvQQ.setVisibility(View.VISIBLE); mIvPyq.setVisibility(View.VISIBLE); mIvWX.setVisibility(View.VISIBLE); } mChange = !mChange;
可用transition/transition_visibility.xml
文件替代
使用<transitionSet xmlns:android="http://schemas.android.com/apk/res/android" android:transitionOrdering="together"> <fade > <targets> <target android:targetId="@+id/iv_link" /> </targets> </fade> <slide android:slideEdge="top"> <targets> <target android:targetId="@+id/iv_qq" /> </targets> </slide> <explode> <targets> <target android:targetId="@+id/iv_pyq" /> <target android:targetId="@+id/iv_wx" /> </targets> </explode> </transitionSet>
TransitionInflater.inflateTransition(int)
导入动画Transition transition = TransitionInflater.from(this) .inflateTransition(R.transition.transition_visibility); TransitionManager.beginDelayedTransition(mContainer, transition);
4. Activity过渡动画
Activity
的切换效果,主要分为4类。
- 从A界面跳转B界面,先调用A的
ExitTransition
,然后调用B的EnterTransition
。 - 从B界面返回A界面,先调用B的
ReturnTransition
(如果没有,使用EnterTransition
),然后调用A的ReenterTransition
(如果没有,使用ExitTransition
)。
需要在Theme
中添加<!-- 添加支持Transations --> <item name="android:windowActivityTransitions">true</item> <!-- 前后两个页面是同步执行还是顺序执行, true为同步 --> <item name="android:windowAllowEnterTransitionOverlap">false</item> <item name="android:windowAllowReturnTransitionOverlap">false</item>
- 通过
Theme
实现,<item name="android:windowEnterTransition">@transition/transition_enter_from_right</item> <item name="android:windowExitTransition">@transition/transition_exit_explode</item>
transition/transition_enter_from_right.xml
文件<transitionSet xmlns:android="http://schemas.android.com/apk/res/android" android:transitionOrdering="together" android:duration="1000"> <fade> <targets> <!-- excludeId 表示我们不需要该 id 的 view 进行过渡转场 --> <target android:excludeId="@android:id/statusBarBackground" /> <target android:excludeId="@android:id/navigationBarBackground" /> </targets> </fade> <slide android:slideEdge="right" > <targets> <target android:excludeId="@android:id/statusBarBackground" /> <target android:excludeId="@android:id/navigationBarBackground" /> </targets> </slide> </transitionSet>
transition/transition_exit_explode.xml
文件
代码调用,低版本可用<transitionSet xmlns:android="http://schemas.android.com/apk/res/android" android:transitionOrdering="together" android:duration="1000"> <explode> <targets> <target android:excludeId="@android:id/statusBarBackground" /> <target android:excludeId="@android:id/navigationBarBackground" /> </targets> </explode> </transitionSet>
ActivityOptionsCompat
替代ActivityOptions
。
效果如下Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(this).toBundle(); startActivity(intent, bundle);
- 代码实现
在A界面中,设置ExitTransition
。
在B界面中,设置Intent intent = new Intent(this, TransitionAnimationResultActivity.class); Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.LEFT).addTarget(R.id.iv_link).addTarget(R.id.iv_pyq)) .addTransition(new Slide(Gravity.RIGHT).addTarget(R.id.iv_qq).addTarget(R.id.iv_wx)) .setDuration(1000); getWindow().setExitTransition(transition); Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(this).toBundle(); startActivity(intent, bundle);
EnterTransition
。
效果如下Transition transition = new TransitionSet() .addTransition(new Fade().addTarget(R.id.iv_link).addTarget(R.id.iv_qq)) .addTransition(new Explode().addTarget(R.id.iv_pyq).addTarget(R.id.iv_wx)) .setDuration(1000); getWindow().setEnterTransition(transition);
5. 多个view的协作动画
首先指定Theme
和过渡动画,
- 实现单个
View
的协作动画
在两个界面的配置文件中指定相同的transitionName
属性
在代码调用android:transitionName="sharedView2"
makeSceneTransitionAnimation(Activity, View, String)
方法
效果如下Intent intent = new Intent(this, TransitionAnimationThemeResultActivity.class); Bundle bundle = ActivityOptions.makeSceneTransitionAnimation( this, mIvQQ, "sharedView2").toBundle(); startActivity(intent, bundle);
- 实现多个
View
的协作动画
首先指定transitionName
属性,并调用makeSceneTransitionAnimation(Activity, Pair)
方法
效果如下Intent intent = new Intent(this, TransitionAnimationThemeResultActivity.class); Bundle bundle = ActivityOptions.makeSceneTransitionAnimation(this, Pair.create(mIvLink, "sharedView1"), Pair.create(mIvQQ, "sharedView2"), Pair.create(mIvPyq, "sharedView3"), Pair.create(mIvWx, "sharedView4")).toBundle(); startActivity(intent, bundle);
相关文章
Animation动画
帧动画
属性动画
组件动画
Transition动画