Android动画(七):过渡动画

Android动画(七):过渡动画

Catalogue

1 场景过渡动画:Scene Transition2 Activity过渡动画:Content Transition、Shared Element Transition2.1 对于共享元素的延迟加载2.2 ViewOverlay 补充2.3 Activity 过渡动画需要注意的点

笔者已将本节的代码上传至 Github,大家可以结合着学习。Android 4.4.2 (API level 19) 引入了 Transition 框架,支持场景过渡效果,到了A ndroid 5.0(API level 21) 开始支持 Activity 过渡动画。相对于视图动画或属性动画,Transition 动画更具特殊性,Transition 可以看作对属性动画的高度封装。为了对 Transition 有一个大体的了解,我们从 Scene Transition(场景过渡动画)、Activity 过渡动画之 Content Transition、Activity 过渡动画之 Shared Element Transition 这三个方面来做概述。

1 场景过渡动画:Scene Transition场景过渡动画是指以动画的形式实现View两个场景的切换(从一个场景切换到另一个场景)。而且在切换过程中通过 Transition 来设置不同的过渡动画效果。场景过渡动画中有三个特别关键概念:Scene(场景),Transition(过渡动画),TransitionManager(管理)。

1、Scene:Scene 代表一个场景。Scene 保存了一个视图层级结构,包括它所有的 views 以及 views 的状态,通常由 getSceneForLayout (ViewGroup sceneRoot,int layoutId,Context context)获取 Scene 实例。Transition 框架可以实现在 starting scene 和 ending scene 之间执行动画。而且大多数情况下,我们不需要创建 starting scene,因为 starting scene 通常由当前UI状态决定,我们只需要创建 ending scene。

2、Transition:Transiton 则是用来设置过渡动画效果用的。而且系统给提供了一些非常有用的 Transtion 动画效果,如下表所示:

| 系统Transition | 解释 || ———- | :———- : || ChangeBounds | 检测 View 的位置边界创建移动和大小变化动画(关注布局边界的变化,不关注 scale 引起的布局边界变化) || ChangeTransform | 检测 View 的 scale 和 rotation 创建缩放和旋转动画(关注 scale 和 ratation 的变化) || ChangeClipBounds | 检测 View 的剪切区域的位置边界,和 ChangeBounds 类似。不过 ChangeBounds 针对的是 view 而 ChangeClipBounds 针对的是 view 的剪切区域 rect 的变化,(关注 setClipBounds(Rect rect) 中 rect 的变化) || ChangeImageTransform | 检测 ImageView 的 ScaleType,并创建相应动画(关注的是 ImageView 的 scaleType) || Fade | 根据 View 的 visibility状态的的不同创建淡入淡动画,调整的是透明度(关注的是 View 的 visibility 的状态) || Slide | 根据 View 的 visibility 状态的的不同创建滑动动画(关注的是 View 的 visibility 的状态) || Explode | 根据 View 的 visibility 状态的的不同创建分解动画(关注的是 View 的 visibility 的状态) || AutoTransition|默认动画,ChangeBounds、Fade 动画的集合|

PathMotionTransition 的辅助工具,以 path 的方式指定过渡效果,两个具体实现类 ArcMotion 和 PatternPathMotion,效果类似于之前讲过的路径动画。参考链接>>

3、TransitionManagerTransitionManager 用于将 Scene 和 Transition 联系起来,它提供了一系列的方法,如:go(Scene scene, Transition transition),到指定的场景所使用的过渡动画是什么,beginDelayedTransition(ViewGroup sceneRoot, Transition transition),在当前场景到下一帧的过渡效果是什么。

我们在使用场景过渡动画时,有两种实现方式。1、TransitionManager.go方式。

123456...//定义开始场景、结束场景。mSceneStart = Scene.getSceneForLayout(sceneRootView, R.layout.scene_start, context);mSceneEnd = Scene.getSceneForLayout(sceneRootView, R.layout.scene_end, context);//开始场景过渡动画。其中"transition"参数可以通过代码生成,如:new AutoTransition()。也可以是引用xml文件,如:TransitionInflater.from(this).inflateTransition(R.transition.xxx)。TransitionManager.go(mSceneEnd,transition);

2、beginDelayedTransition方式。

1234...TransitionManager.beginDelayedTransition(sceneRootView,transition);//下面改变 sceneRootView 中子 View 的属性,如:位置,缩放比例等。...

beginDelayedTransition 的方式是不是会让你联想到之前讲过的 LayoutTransition 动画呢?它们之间的区别可以这么理解:LayoutTransition针对的是各个控件在限定场景到达时的动画表现。而beginDelayedTransition针对的是不同的场景之间的切换动画。前者关注的是控件(微观),后者关注的是场景(宏观)。除了使用系统自带的 Transtion 使用动画以外,我们还可以自定义 Transition 动画,具体可参考官方的这篇文章。或者直接看官方给的DEMO。

使用场景过渡动画需要注意的点:1、Android 版本在 4.0(API Level 14) 到 4.4.2(API Level 19) 使用 Android Support Library,但是Activity过渡动画和共享元素过渡动画至少要Android 5.0版本才支持。2、对于 SurfaceView 可能不起效果,因为 SurfaceView 的实例是在非 UI 线程更新的,因此会造成和其他视图动画不同步。3、某些特定的转换类型在应用到 TextureView 时可能不会产生所需的动画效果。4、继承自 AdapterView 的视图如:ListView,与该框架不兼容。RecycleView 兼容该框架,不过由于 RecycleView 复用机制的存在,这里就会存在两个动画:一个进入、一个退出,所以如果不满足需求,还是老实用 ItemAnimator 吧。(PS:后面再写篇文章详细介绍 RecycleView。)5、不要对包含文本的视图的大小进行动画。(这里所指的大小改变主要包括直接改变视图的宽高或者通过 setTextSize 改变视图的大小,不包括 scale 引起的视图大小变化。)6、默认情况下,sceneRoot 下所有的 View 都会执行 Transition 动画,我们可以通过 Transition.addTarget 和 removeTarget 方法选择性添加或移除执行动画的 View 。需要注意的是,Transition 的 removeTarget 方法必须在已经使用了 addTarget的前提下才有效果。在未使用 addTarget 的情况下,如果要排除某个 View 执行动画效果,可以使用 Transition 的 excludeTarget 替代 removeTarget 方法。

本节参考资料:1、Animate layout changes using a transition2、Android Transition(一)3、Android Transition(Android过渡动画)

2 Activity过渡动画:Content Transition、Shared Element Transition官方参考文档:Start an activity using an animation中文参考文档:Activity 过渡动画

2.1 对于共享元素的延迟加载如果共享元素在被调用的 Activity 需要通过 AsyncTask, Loader, 或其它类似的数据加载方式决定它们最终的表现,数据被分发返回到主线程之前框架是可以开始过渡的。为了解决这个问题,Activity Transitions API 提供了一个方法暂时推迟过渡直到我们确切地知道共享元素已经被适当的渲染和放置。为了从开始时暂时阻止共享元素过渡,调用 postponeEnterTransition()(API >= 21)或 supportPostponeEnterTransition()(API < 21)在你被调用的 Activity 中的 onCreate() 方法中。然后,当你知道所有共享元素已经被适当的摆放和大小时,调用 startPostponedEnterTransition()(API >= 21)或supportStartPostponedEnterTransition()(API < 21) 恢复过渡。你会找到一个常见的处理模式是在 OnPreDrawListener 中开启延迟过渡,它将会在共享元素被渲染和放置后调用。

123456789101112// ... load remote image with Glide/Picasso heresupportPostponeEnterTransition();ivBackdrop.getViewTreeObserver().addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { ivBackdrop.getViewTreeObserver().removeOnPreDrawListener(this); supportStartPostponedEnterTransition(); return true; } });

需要记住的是,一定要在共享元素被渲染和放置后调用startPostponedEnterTransition方法,否者被调用的 Activity 会一直被堵塞。参考文章>>

2.2 ViewOverlay 补充ViewOverlay可以实现跨ViewGroup的动画,参考Demo中的OverlayActivity类,有如下要的:1、动画完成后一定要记得在目标 ViewGroup Overlay 移除当前的View。2、被添加到目标 ViewGroup Overlay 中的 View,无法响应点击事件。

2.3 Activity 过渡动画需要注意的点1、对于非共享元素过渡动画,一些国内机型在开启 windowAllowEnterTransitionOverlap 后,如果 ExitTransition 设置的转场时间过长,则会出现返回页面时无法恢复原来状态的问题。使用经验:如果需要启动页也有动画效果的话,不能将动画时长设置过长,同时要结合多个机型测试一下。另外,不设置 ExitTransition 动画效果不会有问题。2、一些国内机型跳转目标页时,即使使用了 excludeTarget(android.R.id.statusBarBackground, true) 方法排除状态栏参与动画,状态栏背景仍会出现颜色切换现象(颜色为目标页面背景色)。解决方案请参考Demo>>3、使用 Fragment 的 Transition 实现界面过渡可完美避免出现上述问题。 参考项目>>

相关星际资讯

泸州老窖 泸州原浆喜庆装酒52度500ml 浓香型白酒6瓶装
牧野名字的含义
365bet官网娱乐

牧野名字的含义

🕒 07-24 👁️ 2124
世界杯史上十大乌龙球(组图)
28365

世界杯史上十大乌龙球(组图)

🕒 07-20 👁️ 1814