Android编程之Fragment动画加载方法源码详解

上次谈到了Fragment动画加载的异常问题,今天再聊聊它的动画加载loadAnimation的实现源代码:

Animation loadAnimation(Fragment fragment, int transit, boolean enter,
            int transitionStyle) {

接下来具体看一下里面的源码部分,我将一部分一部分的讲解,首先是:

        Animation animObj = fragment.onCreateAnimation(transit, enter,
                fragment.mNextAnim);
        if (animObj != null) {
            return animObj;
        }

开始的这部分,会调用Fragment的onCreateAnimation这个方法,在Fragment类中,这个方法为空,并没有现实:

    /**
     * Called when a fragment loads an animation.
     */
    public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {
        return null;
    }

如果你写的Fragment子类在继承Fragment后重写了这个方法内容,就可以在这里面得到动画。

如果你没有重写这个方法,那就会往下继续:

        if (fragment.mNextAnim != 0) {
            Animation anim = AnimationUtils.loadAnimation(mActivity, fragment.mNextAnim);
            if (anim != null) {
                return anim;
            }
        }

fragment.mNextAnim这个就是在我们添加或者替换fragment的时候,用的FragmentTransaction设置的那个动画,如上篇文章中后面附的那个例子:

        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.setCustomAnimations(R.animator.fragment_rotate_enter,
                R.animator.fragment_rotate_exit,
                R.animator.fragment_rotate_pop_enter,
                R.animator.fragment_rotate_pop_exit);

具体是进入动画,还是退出动画,就要看当时的具体情况了,这个是不需要开发者操心的。

如果我们之前也没定义切换动画,那好吧,就要看我们是否设置transit和transitionStyle参数了:

        if (transit == 0) {
            return null;
        }

        int styleIndex = transitToStyleIndex(transit, enter);
        if (styleIndex < 0) {
            return null;
        }

再看一下transitToStyleIndex方法:

    public static int transitToStyleIndex(int transit, boolean enter) {
        int animAttr = -1;
        switch (transit) {
            case FragmentTransaction.TRANSIT_FRAGMENT_OPEN:
                animAttr = enter ? ANIM_STYLE_OPEN_ENTER : ANIM_STYLE_OPEN_EXIT;
                break;
            case FragmentTransaction.TRANSIT_FRAGMENT_CLOSE:
                animAttr = enter ? ANIM_STYLE_CLOSE_ENTER : ANIM_STYLE_CLOSE_EXIT;
                break;
            case FragmentTransaction.TRANSIT_FRAGMENT_FADE:
                animAttr = enter ? ANIM_STYLE_FADE_ENTER : ANIM_STYLE_FADE_EXIT;
                break;
        }
        return animAttr;
    }

所以,transit的值只能是:FragmentTransaction.TRANSIT_FRAGMENT_OPEN,FragmentTransaction.TRANSIT_FRAGMENT_CLOSE,FragmentTransaction.TRANSIT_FRAGMENT_FADE。然后,会根据这个值,调用系统自己的动画文件:

        switch (styleIndex) {
            case ANIM_STYLE_OPEN_ENTER:
                return makeOpenCloseAnimation(mActivity, 1.125f, 1.0f, 0, 1);
            case ANIM_STYLE_OPEN_EXIT:
                return makeOpenCloseAnimation(mActivity, 1.0f, .975f, 1, 0);
            case ANIM_STYLE_CLOSE_ENTER:
                return makeOpenCloseAnimation(mActivity, .975f, 1.0f, 0, 1);
            case ANIM_STYLE_CLOSE_EXIT:
                return makeOpenCloseAnimation(mActivity, 1.0f, 1.075f, 1, 0);
            case ANIM_STYLE_FADE_ENTER:
                return makeFadeAnimation(mActivity, 0, 1);
            case ANIM_STYLE_FADE_EXIT:
                return makeFadeAnimation(mActivity, 1, 0);
        }

根据之前这些逻辑,代码运行到这里,就应该算是结束了。但该方法,后面还有一些代码:

        if (transitionStyle == 0 && mActivity.getWindow() != null) {
            transitionStyle = mActivity.getWindow().getAttributes().windowAnimations;
        }
        if (transitionStyle == 0) {
            return null;
        }

对比了一样原始包中的FragmentManager,后面这段代码在那边还是有些差异的:

        int styleIndex = transitToStyleIndex(transit, enter);
        if (styleIndex < 0) {
            return null;
        }

        if (transitionStyle == 0 && mActivity.getWindow() != null) {
            transitionStyle = mActivity.getWindow().getAttributes().windowAnimations;
        }
        if (transitionStyle == 0) {
            return null;
        }

        TypedArray attrs = mActivity.obtainStyledAttributes(transitionStyle,
                com.android.internal.R.styleable.FragmentAnimation);
        int anim = attrs.getResourceId(styleIndex, 0);
        attrs.recycle();

        if (anim == 0) {
            return null;
        }

        return AnimatorInflater.loadAnimator(mActivity, anim);

所以,transitionStyle这个参数,在V4包这里是没有意义的。

好了,Fragment这个动画加载的方法内容就这些了。

Android编程之Fragment动画加载方法源码详解,布布扣,bubuko.com

时间: 2024-08-02 07:03:09

Android编程之Fragment动画加载方法源码详解的相关文章

jQuery实现DOM加载方法源码分析

传统的判断dom加载的方法 使用 dom0级 onload事件来进行触发所有浏览器都支持在最初是很流行的写法 我们都熟悉这种写法: window.onload=function(){ ... }  但是onload事件触发过于缓慢,尤其是在存在很多外部图片或者视频文件的时候,为了更好的了解这一点有必要知道一个html文档是如何进行加载的,这里引用一个园友的表述: 1.用户输入网址(假设是个html页面,并且是第一次访问),浏览器向服务器发出请求,服务器返回html文件: 2.浏览器开始载入htm

Android编程之Fragment使用动画造成Unknown animation name: objectAnimator异常

在为Fragment做切换动画,启动后遇到了一个异常: Caused by: java.lang.RuntimeException: Unknown animation name: objectAnimator 截图如下: 我的代码如下: fragment = Fragment.instantiate(getActivity(), clz.getName()); fragment.setArguments(args); ft.setCustomAnimations(R.animator.frag

Android中ViewPager+Fragment懒加载问题解决方案

转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53205878 本文出自[DylanAndroid的博客] Android中ViewPager+Fragment懒加载问题解决方案 在Android中我们经常会用到ViewPager+Fragment组合.然而,有一个很让人头疼的问题就是,我们去加载数据的时候 由于ViewPager的内部机制所限制,所以它会默认至少预加载一个.这让人很郁闷,所以,我就想到要封装一个Fragme

Android App 启动时显示正在加载图片(源码)

微信.QQ.天天动听等程序,在打开时显示了一张图片,然后跳转到相关界面.本文实现这个功能,其实很简单.... 新建两个Activity,LoadingActivity,MainActivity,将LoadingActivity设置为android.intent.action.MAIN.使用TimerTesk,或者Thread将LoadingActivity显示几秒后跳转到MainActivity界面. LoadingActivity: new Timer().schedule(new Timer

spring启动component-scan类扫描加载过程---源码分析

有朋友最近问到了 spring 加载类的过程,尤其是基于 annotation 注解的加载过程,有些时候如果由于某些系统部署的问题,加载不到,很是不解!就针对这个问题,我这篇博客说说spring启动过程,用源码来说明,这部分内容也会在书中出现,只是表达方式会稍微有些区别,我将使用spring 3.0的版本来说明(虽然版本有所区别,但是变化并不是特别大),另外,这里会从WEB中使用spring开始,中途会穿插自己通过newClassPathXmlApplicationContext 的区别和联系.

ElasticSearch 启动时加载 Analyzer 源码分析

ElasticSearch 启动时加载 Analyzer 源码分析 本文介绍 ElasticSearch启动时如何创建.加载Analyzer,主要的参考资料是Lucene中关于Analyzer官方文档介绍.ElasticSearch6.3.2源码中相关类:AnalysisModule.AnalysisPlugin.AnalyzerProvider.各种Tokenizer类和它们对应的TokenizerFactory.另外还参考了一个具体的基于ElasticSearch采用HanLP进行中文分词的

Android View 事件分发机制源码详解(View篇)

前言 在Android View 事件分发机制源码详解(ViewGroup篇)一文中,主要对ViewGroup#dispatchTouchEvent的源码做了相应的解析,其中说到在ViewGroup把事件传递给子View的时候,会调用子View的dispatchTouchEvent,这时分两种情况,如果子View也是一个ViewGroup那么再执行同样的流程继续把事件分发下去,即调用ViewGroup#dispatchTouchEvent:如果子View只是单纯的一个View,那么调用的是Vie

Android ArrayMap源码详解

尊重原创,转载请标明出处    http://blog.csdn.net/abcdef314159 分析源码之前先来介绍一下ArrayMap的存储结构,ArrayMap数据的存储不同于HashMap和SparseArray,在上一篇<Android SparseArray源码详解>中我们讲到SparseArray是以纯数组的形式存储的,一个数组存储的是key值一个数组存储的是value值,今天我们分析的ArrayMap和SparseArray有点类似,他也是以纯数组的形式存储,不过不同的是他的

Ogre动画加载之节点动画、mesh动画及骨骼动画加载方法

在Max中,动画分为两种动画,即Node Animations动画及Mesh Animations动画: 导出文件之后,Node Animations动画是在xx.scene文件中, <node name="huosaixinganzuzhong_qinang_Catheterization"> <position x="-14.3185" y="84.3693" z="39.3585"/> <s