不同方式切换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切换之间的生命周期

刚刚进入程序时生命周期如下:04-11 10:55:32.968 32125-32125/lv.gx.com.fragmentlifecycle I/test: Fragment1---onAttac...

理解Fragment生命周期

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

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

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

让多个Fragment 切换时不重新实例化

在项目中需要进行Fragment的切换,一直都是用replace()方法来替换Fragment: 1 2 3 4 5 6 7 8 9 public void ...

Pro Android学习笔记(四三):Fragment(8):再谈Transaction和管理器

Transaction的一些操作 Transaction提供add()、hide()、show()、remove()等功能。下面我们利用这些功能通过fragment的隐藏和显示,为用户提供切换的效果。...

android之fragment的两种使用方式(add和replace方式切换)

使用过app的人都知道,几乎所有的app都用到fragment进行首页分割,还有的加上了Indicator或者Tablayout或者Viewpager之类的结合使用。总之,fragment是必须掌握的...
  • gsw333
  • gsw333
  • 2016-07-08 11:56
  • 24201

Fragment hide,show方法后,会调用什么方法

在实际开发项目中,经常用到 Fragment,并且为了复用Fragment,所以基本上就是用show()和hide方法来复用Fragment。在Fragment从隐藏到显示,可能会做一些处理,例如数据...

Fragment 切换的两种方式

我们都知道fragment切换有两种方式: 1. replace方式 2. add-hide-show方式

FragmentTransaction使用全解

前言之前已经写过用Fragment做主界面以及Fragment与Activity通信的文章。两篇文章如下: ndroid viewpager+fragment做主界面(超容易理解的demo!) a...

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

上次谈到了Fragment动画加载的异常问题,今天再聊聊它的动画加载loadAnimation的实现源代码: Animation loadAnimation(Fragment fragment, in...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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