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

<?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()实现场景动画,需要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;
    
    效果如下
    这里写图片描述
  • ChangeClipBounds,裁剪位置
    TransitionManager.beginDelayedTransition(mContainer, new ChangeClipBounds());
    
    if (mChange) {
        mImageView.setClipBounds(null);
    } else {
        mImageView.setClipBounds(new Rect(10, 10, 110, 110));
    }
    mChange = !mChange;
    
    效果如下
    这里写图片描述
  • ChangeImageTransform,修改ImageViewScaleTyepe
    TransitionManager.beginDelayedTransition(mContainer, new ChangeImageTransform());
    if (mChange) {
        mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
    } else {
        mImageView.setScaleType(ImageView.ScaleType.CENTER);
    }
    mChange = !mChange;
    
    效果如下
    这里写图片描述
  • 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;
    
    效果如下
    这里写图片描述
    可用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
    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);
    
    效果如下
    这里写图片描述

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

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值