Android过渡动画源码阅读

前言

Android新引入的过渡动画主要使用TransitionManager来实现,主要的实现接口就是go和beginDelayedTransition两个方法。为了能够更好的理解过渡动画的实现机制,现在来分析一下它的实现代码,现在先从go方法开始查看内部的实现。

代码分析

找到TransitionManager.go的实现代码,它又调用了changeScene方法,并且传递进了sDefaultTransition过渡动画。

public static void go(Scene scene) {
    changeScene(scene, sDefaultTransition);
}

changeScene方法内部首先取出了做过渡动画的根布局,然后判断当前根部局有没有已经提交等待了,第一执行sPendingTransitions肯定没有包含当前根布局。由于transition不为空走的就是else里的逻辑,先将根布局加入到等待过渡列表中然后克隆出一个全新的Transition动画,为动画设置根布局对象。

private static void changeScene(Scene scene, Transition transition) {
    final ViewGroup sceneRoot = scene.getSceneRoot();
    if (!sPendingTransitions.contains(sceneRoot)) {
        if (transition == null) {
            scene.enter();
        } else {
            sPendingTransitions.add(sceneRoot);

            Transition transitionClone = transition.clone();
            transitionClone.setSceneRoot(sceneRoot);

            Scene oldScene = Scene.getCurrentScene(sceneRoot);
            if (oldScene != null && oldScene.isCreatedFromLayoutResource()) {
                transitionClone.setCanRemoveViews(true);
            }

            sceneChangeSetup(sceneRoot, transitionClone);

            scene.enter();

            sceneChangeRunTransition(sceneRoot, transitionClone);
        }
    }
}

接下来调用getCurrentScene查看以前保留的Scene对象,第一次调用当然也是没有的,后面就开始调用sceneChangeSetup方法了。

// Scene类方法
static Scene getCurrentScene(View view) {
    return (Scene) view.getTag(com.android.internal.R.id.current_scene);
}

// TransitionManager的类方法
private static void sceneChangeSetup(ViewGroup sceneRoot, Transition transition) {

    // Capture current values
    ArrayList<Transition> runningTransitions = getRunningTransitions().get(sceneRoot);

    if (runningTransitions != null && runningTransitions.size() > 0) {
        for (Transition runningTransition : runningTransitions) {
            runningTransition.pause(sceneRoot);
        }
    }

    if (transition != null) {
        transition.captureValues(sceneRoot, true);
    }

    // Notify previous scene that it is being exited
    Scene previousScene = Scene.getCurrentScene(sceneRoot);
    if (previousScene != null) {
        previousScene.exit();
    }
}

由于是第一次调用runningTransitions和previousScene都是空不会执行后面if里的代码,不过这里调用了transition.captureValues(sceneRoot, true);方法,这个方法就是用来记录下开始Scene里的所有子控件在开始状态下的各种属性值。由于还是第一次调用,所以mTargets里面的数据都是空数据,最终直接调用了captureHierachy方法。


oid captureValues(ViewGroup sceneRoot, boolean start) {
    clearValues(start);
    // mTargetIds第一次执行时候是空的
    if ((mTargetIds.size() > 0 || mTargets.size() > 0)
         ....
    } else {
        // 执行的是captureHierarchy
        captureHierarchy(sceneRoot, start);
    }
    if (!start && mNameOverrides != null) {
        int numOverrides = mNameOverrides.size();
        ArrayList<View> overriddenViews = new ArrayList<View>(numOverrides);
        for (
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值