转场/过渡(Transition) 动画
Transition 是指不同 UI 状态转换时的动画。
界面过渡
界面 的 过渡 可以 分为 进入/出场 的过渡动画
设置进场/出场/返回/重新进入 的过渡场动画:
Window.setEnterTransition(Transition transition) 设置进场动画 主界面-(跳转)->A,A 进入过渡Window.setExitTransition(Transition transition) 设置出场动画 A-(跳转)->B,A 出场过渡Window.setReturnTransition(Transition transition) 设置返回动画 A-(返回)->主界面,A 出场过渡Window.setReenterTransition(Transition transition) 设置重新进入动画 B-(返回)->A,A 进入过渡setAllowEnterTransitionOverlap():是否运行布局显示时重叠setAllowReturnTransitionOverlap():是否运行布局显示时重叠
来看一个界面过渡的动画效果小栗子
看下小栗子代码
// 过渡效果
Explode explode = new Explode(); // 从屏幕中间进入或退出,移动视图
explode.setInterpolator() // 设置插值器
expload.setDuration(1000) // 过渡动效执行时间
// 主界面
getWindow().setReenterTransition(explode); // 重新进入
getWindow().setExitTransition(explode); // 出场
// 界面A
getWindow().setReenterTransition(explode); // 重新进入
getWindow().setExitTransition(explode); // 出场
getWindow().setReturnTransition(explode); // 返回
getWindow().setEnterTransition(explode); // 进入
//界面B
getWindow().setEnterTransition(explode);
getWindow().setReturnTransition(explode);
// 启动Activity,让过渡动画生效
ActivityOptions activityOptions = ActivityOptions.makeSceneTransitionAnimation(TransitionManagerActivity.this);
startActivity(intent, activityOptions.toBundle());
相关知识点1(过渡transition效果) 进入/出场/重新进入/返回过渡效果(这三个类都继承于 Transition ,有一些相同的属性 setDuration,setInterpolator)
Explode(分解):从场景的中心移入或移出 官方API资料Slide(滑动):从场景的边缘移入或移出,滑动 (Gravity 可以设置方向 LEFT, TOP等), [官方API资料] (https://developer.android.google.cn/reference/android/support/transition/Slide)Fade(淡出):调整透明度产生渐变效果 官方API资料
xml方式的过渡效果,类似前面章节动画的XML文件
Transition explode = TransitionInflater.from(this).inflateTransition(R.transition.new_explode);
// 存放的目录为 res/transition/new_explode.xml
android:interpolator="@android:interpolator/插值器" android:duration="2000" /> 主题Style设置 举个栗子: 相关知识点2(ActivityOptions) makeSceneTransitionAnimation(Activity activity, Pair ActivityOptions的小栗子 makeSceneTransitionAnimation 这个在前面已经使用过,后续会讲解的 共享元素界面过渡 的小栗子 makeCustomAnimation 自定义 进入,退出动画 # 从 界面A(exit:no_anim) 进入 界面B(enter:enter_up) ActivityOptionsCompat.makeCustomAnimation(this, R.anim.enter_up, R.anim.no_anim); # 界面B enter:res/anim/enter_up.xml android:duration="10000"> # 界面A exit:res/anim/no_anim.xml android:fromAlpha="1.0" android:toAlpha="0.1" android:duration="10000" /> makeScaleUpAnimation | makeClipRevealAnimation | makeThumbnailScaleUpAnimation 这三种是系统提供的默认动画效果, 我实际使用感觉效果不是很明显, 感觉用处不大. 感兴趣的同学可以自行搜索 makeScaleUpAnimation:比如 界面A 点击某个View,打开B页面,B页面会以相对于View的某个位置放大展开。 ActivityOptions options = ActivityOptions.makeScaleUpAnimation( view, 0, 0, //拉伸开始的坐标 view.getMeasuredWidth(), view.getMeasuredHeight()); // 初始的宽高 startActivity(intent, options.toBundle()); makeClipRevealAnimation:跳转新页面时,新页面的剪切范围逐渐扩大,直到完全显示。(从一个点以圆形渐变到满屏) makeThumbnailScaleUpAnimation:切换时,会先显示一个Bitmap,再过渡到新的页面。 Bitmap bitmap = view.getDrawingCache(); ActivityOptions options = ActivityOptions.makeThumbnailScaleUpAnimation(view, bitmap, 0, 0); startActivity(intent, options.toBundle()); 相关知识点3(过渡transition效果2) ChangeBounds - 检测view的位置边界创建移动和缩放 过渡动画ChangeClipBounds - 检测view的scale和rotation创建缩放和旋转动画ChangeTransform - 检测view的剪切区域的位置边界,和ChangeBounds类似。不过ChangeBounds针对的是view而ChangeClipBounds针对的是view的剪切区域(setClipBound(Rect rect) 中的rect)。如果没有设置则没有动画效果ChangeImageTransform - 检测ImageView(这里是专指ImageView)的尺寸,位置以及ScaleType,并创建相应动画。 以上的 继承Transiton类 后续的布局场景切换会使用这个知识点来讲解. 参考资料 自定义transition 当然你可以继承Transition,编写自己的自定义 Transition. 感兴趣的同学可以自行搜索相关资料. public class CustomTransition extends Transition { @Override public void captureStartValues(TransitionValues values) {} @Override public void captureEndValues(TransitionValues values) {} @Override public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) {} } 场景小剧场 这里可以看看 Launcher3 startActivity 的使用,启动第三方的应用,保持了统一的启动过渡动画,它的方式也是安全启动的代码; 建议编写电视相关的桌面的时候按照Launcher3的方式来写. 代码片段 共享元素界面过渡 从一个界面 跳转 到 一个新的界面,界面元素 过渡 到 新界面的元素上. 如何去实现共享元素的过渡的动画效果 比如 Activity1 跳转到 Activity2,共享元素 view1->view2: 为两个页面的共享元素指定同样 的 transitionName # Activity1,你需要设置 view1 的 transitionName 的名称为 "ShardTest" Intent intent = new Intent(this, Activity2.class); ActivityOptions options = ActivityOptions .makeSceneTransitionAnimation(this, view1, "ShardTest"); startActivity(intent, options.toBundle()); # activity2 的 view2 需要和 Activity2 的 view1 的 transitionName 的名称保持一致. 1. 代码中使用(代码中使用View.setTransitionName(String)方法) ViewCompat.setTransitionName(view2, "ShardTest"); 2. 布局XML中指定(在布局文件中使用android:transitionName属性) android:transitionName="robot" 如果界面上又多个共享元素,要如何写? 如果有多个共享元素,也可以使用下面的方式: Pair.create(view2, "ShardTestOne") new Pair ActivityOptionsCompat.makeSceneTransitionAnimation(this, Pair.create(view1, "ShardTestOne"), Pair.create(view11, "ShardTestTwo")); 在另外一端,也需要处理多个共享元素: ViewCompat.setTransitionName(view2, "ShardTestOne"); ViewCompat.setTransitionName(view22, "ShardTestTwo"); // 或者布局中指定(android:transitionName),这里不过多解释,同上 看看效果,这就是imageview与TextView共享元素的效果 电视系统中 SystemUI 最近任务的共享元素的过渡动画效果 栗子,可以看看效果(从系统设置的界面到最近任务界面的缩略图布局) TranstionManger + Screne(场景) 布局过渡 Android L(api19) 引入的场景(Scene)动画的扩展. 使开发者更加方便的实现布局(界面)变化时候的过渡动画. 相关API: Scene.getSceneForLayout(ViewGroup sceneRoot, int layoutId, Context context) 根据布局ID,加载一个场景Scene(ViewGroup sceneRoot, View view) 根据 view, 加载一个场景TransitionManager.go(Scene scene, Transition transition) 切换场景布局TransitionManager.beginDelayedTransition 保存一个当前视图树状态的场景, 参考官方的API文档 举几个小栗子 两个布局的过渡 // 从布局生成场景(Scene) final Scene scene1 = Scene.getSceneForLayout(container, R.layout.scene1_layout, context); // View scene1Layout = LayoutInflater.from(context).inflate(R.layout.scene1_layout, null); final Scene scene2 = Scene.getSceneForLayout(container, R.layout.scene2_layout/*scene1Layout*/, context); TransitionManager.go(scene1, new Fade()); // fade_in 淡入视图,fade_out 淡出视图,fade_in_out(默认) TransitionManager.go(scene2, new Fade()); 一个界面中的两个 view 过渡 final Scene scene1 = new Scene(containerView, imageview1); final Scene scene2 = new Scene(container, imageview2); TransitionManager.go(scene1, transition); TransitionManager.go(scene2, transition); 控件的属性改变的过渡 ChangeBounds transition = new ChangeBounds(); // 执行TransitionManager.beginDelayedTransition后,会保存一个当前视图树状态的场景 TransitionManager.beginDelayedTransition(containerView, transition); // ViewGroup.LayoutParams lp = containerView.getLayoutParams(); lp.width = 200; // width = 500; lp.height = 200; // height = 500; container.setLayoutParams(lp); 如果上面的栗子不太直观,可以看看其它的效果(改变了宽高,隐藏,显示 属性,使用的 explode + Changebounds) 可以使用XML方式加载过渡效果 Transition transition = TransitionInflater.from(context).inflateTransition(R.transition .test_trantion); // test_trantion.xml android:duration="1500" android:interpolator="@android:interpolator/decelerate_cubic"> 再看一个 Changebounds 小栗子效果 相关DEMO代码 感兴趣的小伙伴 查询 官方资料 或者 搜索相关资料 也可以了解 最新的 布局过渡 ConstraintLayout 2.0 的 motionlayout 注意 1.从 Activity1 跳转到 Activity2 的后,如果要退出 Activity2 ,调用 Activity.finishAfterTransition(),不要调用 Activity.finish(). 不然没有从 Activity2 回到 Activity1 的动画效果. 2.如果不生效可以加入支持 // 1. 主题 // 2. 代码加入,记得要在 setContentView 之前加. getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); setContentView(R.layout.activity_start_anim); 3.Overlay的具体效果不太明白,但是从语义来说应该是让动画更加的融合自然。禁用(false)/开启(true) 默认效果 getWindow().setSharedElementsUseOverlay(true); 参考资料 谷歌过渡动画指南 过渡动画视频1 过渡动画视频2 高逼格Android转场动画 Android转场动画和共享元素动画兼容5.0以下版本的实现 动起来!动起来!- Android Transitions 转场动画 Android炫酷的Activity切换效果,共享元素 Android动画之Transition和TransitionManager使用 Android Transition Framework详解—超炫的动画框架 A beginners guide to implement Android Animations (Part 2) Animate all the things. Transitions in Android 程序员与设计/动效师的沟通工具 Android动画了解—属性动画(Property Animation)<=上个章节 下个章节=> Android动画了解—RecyclerView Animator