Android Transition动画学习笔记
来源:互联网 发布:socketselect php 编辑:程序博客网 时间:2024/06/06 13:22
概述
Android 4.4.2 (API level 19)引入Transition框架,之后很多APP上都使用该框架做出很酷炫的效果,如 Google Play Newsstand app
还有github上很火的plaid
在app中适当得使用上Transition能带来较好的用户体验,视频中介绍了该框架的基本使用以及其中核心的一些类和方法,只有学会这些基本的API才能在之后的Activity/Fragment过渡定制一些自己想要的效果。
先看官网的一张关系图
图中有三个核心的类,分别是Scene、Transition和TransitionManager,下面对这个三个核心类展开分析。
Scene
Scene场景,用于保存布局中所有View的属性值,创建Scene的方式可以通过getSceneForLayout方法
getSceneForLayout(ViewGroup sceneRoot, int layoutId, Context context)
比如:
12
mScene0 = Scene.getSceneForLayout(mSceneRoot, R.layout.scene0, getContext());mScene1 = Scene.getSceneForLayout(mSceneRoot, R.layout.scene1, getContext());
也可以直接new Scene(ViewGroup sceneRoot, View layout)
1234
View view0 = inflater.inflate(R.layout.scene0, container, false);View view1 = inflater.inflate(R.layout.scene1, container, false);mScene0 = new Scene(mSceneRoot, view0);mScene1 = new Scene(mSceneRoot, view1);
两种方式都需要传SceneRoot,即该场景的根节点。
Transition
Transition过渡动画,前面创建了两个场景,分别保存了视图的一些属性,比如Visibility、position等,Transition就是对于这些属性值的改变定义过渡的效果。从上图可以看到系统内置了一些常用的Transition,Transition的创建可以通过加载xml,如:
res/transition/fade_transition.xml
1
<fade xmlns:android="http://schemas.android.com/apk/res/android" />
然后在代码中:
123
Transition mFadeTransition =TransitionInflater.from(this).inflateTransition(R.transition.fade_transition);
或者直接在代码中:
1
Transition mFadeTransition = new Fade();
TransitionManager
TransitionManeger用于将Scene和Transition联系起来,它提供了一系列的方法如setTransition(Scene fromScene, Scene toScene, Transition transition)指明起始场景和结束场景、他们的过渡动画是什么,go(Scene scene, Transition transition),到指定的场景所使用的过渡动画是什么,beginDelayedTransition(ViewGroup sceneRoot, Transition transition),在当前场景到下一帧的过渡效果是什么。比如这里使用go()方法,效果:
注意这里两个Scene中红绿两个方块除了位置和大小不一样,id是一致的,transition记录下两个Scene前后属性值,根据属性值的改变执行过渡动画,默认情况下对SceneRoot下的所有View执行动画效果,我们可以通过Transition.addTarget和removeTarget方法选择性添加或移除执行动画的View。
常用API
有时候我们只想改变当前已展示的视图层级中View的状态,可以通过beginDelayedTransition实现,下面列举系统内置的Transition的使用。
AutoTransition
AutoTransition默认的动画效果,对应xml tag为autoTransition
其实是以下几个动画组合顺序执行:
123456
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"android:transitionOrdering="sequential"><fade android:fadingMode="fade_out" /><changeBounds /><fade android:fadingMode="fade_in" /></transitionSet>
在代码中使用:
123456
TransitionManager.beginDelayedTransition(mRoot, new AutoTransition());if (mTextView.getVisibility() != View.VISIBLE) {mTextView.setVisibility(View.VISIBLE);} else {mTextView.setVisibility(View.GONE);}
ChangeBounds
ChangeBounds对应xml tag为changeBounds
,根据前后布局界限的变化执行动画
12345678
TransitionManager.beginDelayedTransition(mRoot, new ChangeBounds());FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mTarget.getLayoutParams();if ((lp.gravity & Gravity.START) == Gravity.START) {lp.gravity = Gravity.BOTTOM | Gravity.END;} else {lp.gravity = Gravity.TOP | Gravity.START;}mTarget.setLayoutParams(lp);
ChangeClipBounds
ChangeClipBounds对应xml tag为changeClipBounds
,作用对象:View的getClipBounds()值
1234567
Rect BOUNDS = new Rect(20, 20, 100, 100);TransitionManager.beginDelayedTransition(mRoot, new ChangeClipBounds());if (BOUNDS.equals(ViewCompat.getClipBounds(mImageView))) {ViewCompat.setClipBounds(mImageView, null);} else {ViewCompat.setClipBounds(mImageView, BOUNDS);}
ChangeImageTransform
对应xml tag为changeImageTransform
,作用对象:ImageView的matrix
12
TransitionManager.beginDelayedTransition(mRoot, new ChangeImageTransform());mImageView.setScaleType(ImageView.ScaleType.XXX);
ChangeScroll
对应xml tag为changeScroll
,作用对象:View的scroll属性值
12
TransitionManager.beginDelayedTransition(mRoot, new ChangeScroll());mTarget.scrollBy(-100, -100);
ChangeTransform
对应xml tag 为changeTransform,作用对象:View的scale和rotation
123456789101112131415
TransitionManager.beginDelayedTransition(mRoot, new ChangeTransform());if (mContainer2.getChildCount() > 0) {mContainer2.removeAllViews();showRedSquare(mContainer1);} else {mContainer1.removeAllViews();showRedSquare(mContainer2);mContainer2.getChildAt(0).setRotation(45);}private void showRedSquare(FrameLayout container) {final View view = LayoutInflater.from(getContext()).inflate(R.layout.red_square, container, false);container.addView(view);}
Explode
对应xml tag为explode
,作用对象:View的Visibility
12345
TransitionManager.beginDelayedTransition(mRoot, new Explode());int vis = mViews.get(0).getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE;for (View view : mViews) {view.setVisibility(vis);}
Fade
对应xml tag为fade
,作用对象:View的Visibility
可以在初始化时指定IN或者OUT分别对应淡入和淡出,也可以通过fade.setMode方法设置,若不指定默认为淡入淡出效果
12345
TransitionManager.beginDelayedTransition(mRoot, new Fade());int vis = mViews.get(0).getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE;for (View view : mViews) {view.setVisibility(vis);}
Slide
对应xml tag为slide
,作用对象:View的Visibility
可以初始化时传入Gravity.XX,也可以通过slide.setSlideEdge方法设置,默认方向为Gravity.BOTTOM
12345
TransitionManager.beginDelayedTransition(mRoot, new Slide());int vis = mViews.get(0).getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE;for (View view : mViews) {view.setVisibility(vis);}
TransitionSet
对应xml tag为transitionSet
可以在代码中创建transitionSet如:
123456789101112
mTransition = new TransitionSet();mTransition.addTransition(new ChangeImageTransform());mTransition.addTransition(new ChangeTransform());TransitionManager.beginDelayedTransition(mOuterFrame, mTransition);if (mInnerFrame.getChildCount() > 0) {mInnerFrame.removeAllViews();addImageView(mOuterFrame, ImageView.ScaleType.CENTER_CROP, mPhotoSize);} else {mOuterFrame.removeViewAt(1);addImageView(mInnerFrame, ImageView.ScaleType.FIT_XY,FrameLayout.LayoutParams.MATCH_PARENT);}
也可以通过加载xml布局创建transitionSet:
xml布局长这样:
123456
<?xml version="1.0" encoding="utf-8"?><transitionSet xmlns:android="http://schemas.android.com/apk/res/android"android:transitionOrdering="together"><changeImageTransform/><changeTransform/></transitionSet>
通过transitionOrdering属性设置动画执行的顺序,together表示同时执行,sequential表示顺序执行,在代码中可以调用TransitionSet的setOrdering(int)方法,属性值传ORDERING_SEQUENTIAL或者ORDERING_TOGETHER
在代码中:
12345678910
mTransition = (TransitionSet) TransitionInflater.from(getContext()).inflateTransition(R.transition.transition);TransitionManager.beginDelayedTransition(mOuterFrame, mTransition);if (mInnerFrame.getChildCount() > 0) {mInnerFrame.removeAllViews();addImageView(mOuterFrame, ImageView.ScaleType.CENTER_CROP, mPhotoSize);} else {mOuterFrame.removeViewAt(1);addImageView(mInnerFrame, ImageView.ScaleType.FIT_XY,FrameLayout.LayoutParams.MATCH_PARENT);}
这里结合changeImageTransform和changeTransform,效果如下:
PathMotion
Transition的辅助工具,以path的方式指定过渡效果,两个具体实现类ArcMotion和PatternPathMotion,看下ArcMotion的效果
12345678910
mTransition = new AutoTransition();mTransition.setPathMotion(new ArcMotion());TransitionManager.beginDelayedTransition(mRoot, mTransition);FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mTarget.getLayoutParams();if ((lp.gravity & Gravity.START) == Gravity.START) {lp.gravity = Gravity.END | Gravity.BOTTOM;} else {lp.gravity = Gravity.START | Gravity.TOP;}mTarget.setLayoutParams(lp);
它的运动轨迹是条曲线,有兴趣的可以研究下它的实现算法,在源码中有个很萌的图如下:
自定义Transition
除了系统内置的Transition,我们还可以自定义Transition效果,需要继承Transition
123456789101112
public class CustomTransition extends Transition {@Overridepublic void captureStartValues(TransitionValues values) {}@Overridepublic void captureEndValues(TransitionValues values) {}@Overridepublic Animator createAnimator(ViewGroup sceneRoot,TransitionValues startValues,TransitionValues endValues) {}}
其工作原理是在captureStartValues和captureEndValues中分别记录View的属性值,官网建议确保属性值不冲突,属性值的命名格式参考:
1
package_name:transition_name:property_name
在createAnimator中创建动画,对比属性值的改变执行动画效果,如自定义修改颜色动画效果:
在两个Scene中使用自定义过渡动画,效果如下:
Note
1.Android 版本在4.0(API Level 14)到4.4.2(API Level 19)使用Android Support Library’s
2.对于 SurfaceView可能不起效果,因为SurfaceView的实例是在非UI线程更新的,因此会造成和其他视图动画不同步。
3.某些特定的转换类型在应用到TextureView时可能不会产生所需的动画效果。
4.继承自AdapterView的如ListView,与该框架不兼容。
5.不要对包含文本的视图的大小进行动画
Thanks to
Google Demo
Github Demo传送门
- 本文作者: HuYounger
- 本文标题: Transition学习笔记
- 本文链接: http://rkhcy.github.io/2017/09/21/TransitionNote/
- 发布时间:2017年9月21日 - 00时09分
- 版权声明: 本文由 HuYounger 原创,采用 保留署名-非商业性使用-禁止演绎 4.0-国际许可协议
转载请保留以上声明信息!
- Android Transition动画学习笔记
- Android Transition动画学习笔记 2
- Android 笔记 transition / 转换动画
- Android Transition 学习笔记
- Android学习笔记之Transition——Transition简单动画(1)
- Android自定义Transition动画
- Android动画:Transition
- Android Transition动画
- Android自定义Transition动画
- android 动画 过渡动画 transition
- 【代码笔记】iOS-Transition动画
- Android动画--Activity过渡动画 Transition
- Android 笔记 transition 补充 --content transition / activity transition
- android动画学习笔记
- Android动画学习笔记
- Android动画学习笔记
- Android动画学习笔记
- Android 动画学习笔记
- Linux 虚拟机虚拟网卡问题导致无法连接问题
- Java xml编程
- git flow 使用
- UE4动作流程总结
- 轻量级后台框架----ACE Admin依赖*.css&&*.min.js简要概述
- Android Transition动画学习笔记
- bzoj 3232: 圈地游戏
- UOJ 265(状压dp)(NOIP2016)
- Cordova问题集合
- 位运算 之&、 |、 ^
- hashCode的作用
- display和visibility的区别
- 将自定义函数 helloUDF2 注册到hive 源码中,并且重新编译hive
- 高性能负载均衡设计与实现