Android Transition动画

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()实现场景动画,需要SceneTransitionScene通过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文件


<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文件


<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>

效果如下
Android Transition动画_第1张图片

3. TransitionManager.beginDelayedTransition场景动画

TransitionManager.beginDelayedTransition()实现场景动画,需要sceneRootTransition

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;
    
    效果如下
    Android Transition动画_第2张图片
  • ChangeClipBounds,裁剪位置
    TransitionManager.beginDelayedTransition(mContainer, new ChangeClipBounds());
    
    if (mChange) {
        mImageView.setClipBounds(null);
    } else {
        mImageView.setClipBounds(new Rect(10, 10, 110, 110));
    }
    mChange = !mChange;
    
    效果如下
    Android Transition动画_第3张图片
  • ChangeImageTransform,修改ImageViewScaleTyepe
    TransitionManager.beginDelayedTransition(mContainer, new ChangeImageTransform());
    if (mChange) {
        mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
    } else {
        mImageView.setScaleType(ImageView.ScaleType.CENTER);
    }
    mChange = !mChange;
    
    效果如下
    Android Transition动画_第4张图片
  • FadeSlideExplode,修改visibility。利用TransitionSet实现多种动画,需要指定TargetSlide可指定方向。
    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;
    
    效果如下
    Android Transition动画_第5张图片
    可用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中添加
    
    <item name="android:windowActivityTransitions">trueitem>
    
    <item name="android:windowAllowEnterTransitionOverlap">falseitem>
    <item name="android:windowAllowReturnTransitionOverlap">falseitem>
    
  • 通过Theme实现,
    <item name="android:windowEnterTransition">@transition/transition_enter_from_rightitem>
    <item name="android:windowExitTransition">@transition/transition_exit_explodeitem>
    
    transition/transition_enter_from_right.xml文件
    <transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
        android:transitionOrdering="together"
        android:duration="1000">
        <fade>
            <targets>
                
                <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);
    
    效果如下
    Android Transition动画_第6张图片
  • 代码实现
    在A界面中,设置ExitTransition
    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);
    
    在B界面中,设置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);
    
    效果如下
    Android Transition动画_第7张图片

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);
    
    效果如下
    Android Transition动画_第8张图片
  • 实现多个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);
    
    效果如下
    Android Transition动画_第9张图片

相关文章
Animation动画
帧动画
属性动画
组件动画
Transition动画

你可能感兴趣的:(Android,图像动画,android,Transition动画)