不同方式切换Fragment时,生命周期的回调的不同

原创 2016年08月30日 11:21:57

先上张Fragment 生命周期图

这里写图片描述

下面开始通过不同的Fragment的切换方式来分别说明生命周期的调用

  1. 通过add hide show 方式来切换Fragment
切换方法使用:
@Override
    public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
        mFragmentTransaction = getSupportFragmentManager().beginTransaction();//每次切换Fragment 都需要获取一次新的,transaction不能重复调用,要重新实例transaction
        hideFragment(mFragmentTransaction);
        switch (checkedId) {
            case R.id.rb_fragment1:
                if (fragment1 == null) {
                    fragment1 = new Fragment1();
                    mFragmentTransaction.add(R.id.rl_content, fragment1);
                } else {
                    mFragmentTransaction.show(fragment1);
                }
                mFragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
                break;
            case R.id.rb_fragment2:
                if (fragment2 == null) {
                    fragment2 = new Fragment2();
                    mFragmentTransaction.add(R.id.rl_content, fragment2);
                } else {
                    mFragmentTransaction.show(fragment2);
                }

                mFragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
                break;
        }
        mFragmentTransaction.commit();
    }

    /**
     * 隐藏界面
     *
     * @param transaction
     */
    private void hideFragment(FragmentTransaction transaction) {
        if (fragment1 != null) {
            transaction.hide(fragment1);
        }
        if (fragment2 != null) {
            transaction.hide(fragment2);
        }
    }
这种方式切换时的生命周期

载入Fragment1
Fragment1 onCreate
Fragment1 onCreateView
Fragment1 onStart
Fragment1 onResume
切换Fragment2:
(Fragment1不走任何生命周期,但会调onHiddenChanged方法)
Fragment2 onCreate
Fragment2 onCreateView
Fragment2 onStart
Fragment2 onResume
回到Fragment1:
(Fragment2不走任何生命周期,但会调onHiddenChanged方法)
总结:用这种方法切换,Fragment在隐藏时并不会走onDestoryView,所以显示时也不会走onCreateView,所有View都一直保存在内存中。

  1. 通过replace 方式来切换Fragment
切换方法使用:
 @Override
    public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
        mFragmentTransaction = getSupportFragmentManager().beginTransaction();//每次切换Fragment 都需要获取一次新的,transaction不能重复调用,要重新实例transaction
        switch (checkedId) {
            case R.id.rb_fragment1:
                if (fragment1 == null) {
                    fragment1 = new Fragment1();
                }
                mFragmentTransaction.replace(R.id.rl_content, fragment1);
                mFragmentTransaction.addToBackStack(null);
                mFragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
                break;
            case R.id.rb_fragment2:
                if (fragment2 == null) {
                    fragment2 = new Fragment2();
                }
                mFragmentTransaction.replace(R.id.rl_content, fragment2);
                mFragmentTransaction.addToBackStack(null);
                mFragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
                break;
        }
        mFragmentTransaction.commit();
    }

载入Fragment1生命周期与上面相同:
Fragment1 onCreate
Fragment1 onCreateView
Fragment1 onStart
Fragment1 onResume
切到Fragment2:
这次的Fragment1走生命周期了
Fragment1 onPause
Fragment1 onStop
Fragment1 onDestoryView
Fragment1 onDestory
Fragment2 onCreate
Fragment2 onCreateView
Fragment2 onStart
Fragment2 onResume
真实打印出来Fragment1走了onDestory,被完全回收了!
再切回到Fragment1
Fragment1 onCreate
Fragment1 onCreateView
Fragment1 onStart
Fragment1 onResume
Fragment2 onPause
Fragment2 onStop
Fragment2 onDestoryView
Fragment2 onDestory
Fragment1因为已经被回收,又走onCreate,Fragment2被回收。
3. 通过ViewPager 方式来切换Fragment
ViewPager中的Fragment 都会提前初始化
以三个Fragment 的为例来说三个Fragment会提前初始化,初始化view,这样也是用户体验很好的,先预加载view,然后再加载数据
初始化时的生命周期:
D/FragmentA: onCreate
D/FragmentA: onCreateView
D/FragmentB: onCreate
D/FragmentB: onCreateView
D/FragmentC: onCreate
D/FragmentC: onCreateView
切换到FragmentB:
(不走任何生命周期,只会调用setUserVisibleHint方法)
D/FragmentB: setUserVisibleHint
切换到FragmentC:
(不走任何生命周期,只会调用setUserVisibleHint方法)
D/FragmentC: setUserVisibleHint
再切回去也是这样
如此一来我们可以通过此方法判断是否为显示状态
注意:但是setUserVisibleHint方法只有在切换的时候调用,但是第一个fragment第一个显示的时候是不调用这个方法,所以需要注意的是第一个要显示的Fragmet需要做处理

/**
 * 第一个fragemnt要做处理,调用第一个fragment setUserVisibleHint(true); 方法,因为setUserVisibleHint(true);方法只有切换的时候才会调用,所以初始化时,要让第一个先显示,
 * 但是setUserVisibleHint会优先onCreate 方法只想,这样会有空指针问题,所以使用标记记住是否初始化完成,完成后再请求数据
 * @param savedInstanceState
 */
@Override
public void onActivityCreated(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    setUserVisibleHint(true);
    super.onActivityCreated(savedInstanceState);
}
```我们通过主动调用setUserVisibleHint来控制第一次不会调用setUserVisibleHint方法的问题,但是setUserVisibleHint方法会优先onCreateView方法调用,当onCreateView方法调用后还会再调用一次setUserVisibleHint方法,这时我们要对是否调用了onCreateView方法进行标记判断





<div class="se-preview-section-delimiter"></div>

/**
* 标志位,标志已经初始化完成
*/
private boolean isPrepared;

/**
* 第一个fragemnt要做处理,调用第一个fragment setUserVisibleHint(true); 方法,因为setUserVisibleHint(true);方法只有切换的时候才会调用,所以初始化时,要让第一个先显示,
* 但是setUserVisibleHint会优先onCreate 方法只想,这样会有空指针问题,所以使用标记记住是否初始化完成,完成后再请求数据
* @param savedInstanceState
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
setUserVisibleHint(true);
super.onActivityCreated(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_a, container, false);
isPrepared = true;//已经初始化
Log.d(this.getClass().getSimpleName(), “onCreateView”);
return view;
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);

if (isPrepared && isVisibleToUser) {//可见的并且是初始化之后才加载
Log.d(this.getClass().getSimpleName(), "请求数据");
}

}
“`

/**
 * 标志位,标志已经初始化完成
 */
private boolean isPrepared;


/**
 * 第一个fragemnt要做处理,调用第一个fragment setUserVisibleHint(true); 方法,因为setUserVisibleHint(true);方法只有切换的时候才会调用,所以初始化时,要让第一个先显示,
 * 但是setUserVisibleHint会优先onCreate 方法只想,这样会有空指针问题,所以使用标记记住是否初始化完成,完成后再请求数据
 * @param savedInstanceState
 */
@Override
public void onActivityCreated(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    setUserVisibleHint(true);
    super.onActivityCreated(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_a, container, false);
    isPrepared = true;//已经初始化
    Log.d(this.getClass().getSimpleName(), "onCreateView");
    return view;
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if (isPrepared && isVisibleToUser) {//可见的并且是初始化之后才加载
    Log.d(this.getClass().getSimpleName(), "请求数据");
    }
}

代码地址:https://github.com/jiangshujing/FragmentDemo.git

版权声明:本文为博主原创文章,未经博主允许不得转载。

理解Fragment生命周期

官网帮助文档链接:  http://developer.android.com/guide/components/fragments.html 主要看两张图,和跑代码 一,Fragment的生命...

ViewPager+Fragment中fragment之间的切换的时候怎么设置调用onresume()

OnPageChangeListener opc = new OnPageChangeListener() { @Override public void onPageSelected(int arg...

怎么让Fragment 切换时不重新执行生命周期的方法

> fragment是我们经常使用到的一个控件,但是,相信大家会出现这样的一个问题,每次切换fragment的时候,fragment就会重新调用一次生命周期的方法,从而会重新加载一次数据,这样既消耗用...

Android快速分析apk工具aapt的使用教程

aapt简介 aapt即Android Asset Packaging Tool,我们可以在SDK的platform-tools目录下找到该工具。aapt可以查看、 创建、 更新ZIP格式的文档...

一道面试题:两个Fragment在replace/add 和 hide/show不同情况下来回跳转生命周期的变化

今天面试,只能说如同当头棒喝,很多小细节掌握的并不好。废话不多说,记录一下这个问题。             1.在replace的情况下,FragmentA显示,正常调用生命周期运行如下:...

Fragment间切换生命周期方法的回调顺序

-------- Fragment1默认打开,然后再由Activity打开Fragment2 Fragment1 public class Fragment1 extends Fragment {...
  • musk6
  • musk6
  • 2017年03月30日 21:33
  • 333

Android_不同行为的Fragement的生命周期的变化

想要清楚Fragment的生命周期变化一定要理解回退栈的作用,回退栈是栈,所以是先进后出,后进先出.点击back键的时候,最先被销毁的应该是最后添加到栈的对象。 代码比较简单,所以就不写了,简单的描...

数据库优化 in 软件生命周期的不同阶段

之前写过一系列关于mysql优化的文章,今天在网上看到一篇关于SQL SERVER优化的介绍,该文将数据库优化和软件开发周期结合在一起,看完后填补了很多知识的缺漏,感觉非常不错,故分享之。 ====...

Hibernate学习--Session生命周期的不同状态

前言总结一下Session的不同状态。Session的生命周期不同状态三种状态Hibernate生命周期中java对象的三种状态: 1、临时状态(transient):用new语句创建,还没有被持...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:不同方式切换Fragment时,生命周期的回调的不同
举报原因:
原因补充:

(最多只允许输入30个字)