Different callbacks in life cycle when switching fragments in different ways

Keywords: Fragment github git

turn http://blog.csdn.net/hjiangshujing/article/details/52367734


Previous Fragment Life Cycle Map

Here's how to switch between different Fragment s to illustrate life cycle calls

  1. Switch Fragment s by adding hide show
Switching method uses:
@Override
    public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
        mFragmentTransaction = getSupportFragmentManager().beginTransaction();//Each switching Fragment requires a new one, transaction cannot be called repeatedly, transaction is re-instantiated
        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();
    }

    /**
     * Hide interface
     *
     * @param transaction
     */
    private void hideFragment(FragmentTransaction transaction) {
        if (fragment1 != null) {
            transaction.hide(fragment1);
        }
        if (fragment2 != null) {
            transaction.hide(fragment2);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
Lifecycle when switching this way

Load Fragment1
Fragment1 onCreate 
Fragment1 onCreateView 
Fragment1 onStart 
Fragment1 onResume 
Switch Fragment2:
(Fragment1 does not take any life cycle, but reconciles the onHiddenChanged method)
Fragment2 onCreate 
Fragment2 onCreateView 
Fragment2 onStart 
Fragment2 onResume 
Back to Fragment1:
(Fragment2 does not go through any life cycle, but reconciles the onHiddenChanged method)
Summary: By switching this way, Fragment s do not walk onDestoryView when hidden, so they do not walk onCreateView when displayed, and all views are kept in memory.

  1. Switch Fragment s by replace
Switching method uses:
 @Override
    public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
        mFragmentTransaction = getSupportFragmentManager().beginTransaction();//Each switching Fragment requires a new one, transaction cannot be called repeatedly, transaction is re-instantiated
        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();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

Loading Fragment1 has the same lifecycle as above:
Fragment1 onCreate 
Fragment1 onCreateView 
Fragment1 onStart 
Fragment1 onResume 
Cut to Fragment2:
This time Fragment1 is going through its life cycle.
Fragment1 onPause 
Fragment1 onStop 
Fragment1 onDestoryView 
Fragment1 onDestory 
Fragment2 onCreate 
Fragment2 onCreateView 
Fragment2 onStart 
Fragment2 onResume 
True printout Fragment1 takes onDestory and is completely recycled!
Cut back to Fragment1
Fragment1 onCreate 
Fragment1 onCreateView 
Fragment1 onStart 
Fragment1 onResume 
Fragment2 onPause 
Fragment2 onStop 
Fragment2 onDestoryView 
Fragment2 onDestory 
Fragment1 was recycled because it had already been recycled, and then onCreate, Fragment2 was recycled.(
3. Switch Fragment s by ViewPager
Fragment s in ViewPager are all initialized in advance
In the case of three fragments, three fragments initialize the view ahead of time, which is also a good user experience, pre-loading the view before loading the data.
Life cycle at initialization:
D/FragmentA: onCreate 
D/FragmentA: onCreateView 
D/FragmentB: onCreate 
D/FragmentB: onCreateView 
D/FragmentC: onCreate 
D/FragmentC: onCreateView 
Switch to FragmentB:
(Without going through any life cycle, only the setUserVisibleHint method will be called)
D/FragmentB: setUserVisibleHint 
Switch to FragmentC:
(Without going through any life cycle, only the setUserVisibleHint method will be called)
D/FragmentC: setUserVisibleHint 
It's the same when you cut back.
This way we can determine if it is a display state or not.
Note: However, the setUserVisibleHint method is only called when switching, but it is not called when the first fragment is first displayed, so it is important to note that the first Fragmet to be displayed needs to be handled

/**
 * The first fragemnt is to be processed, calling the first fragment setUserVisibleHint(true); the method, because setUserVisibleHint(true); the method is called only when it is switched, so when initializing, let the first show first.
 * But setUserVisibleHint takes precedence over the onCreate method just because it has a null pointer problem, so use markup to remember if initialization is complete and request data when it is done
 * @param savedInstanceState
 */
@Override
public void onActivityCreated(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    setUserVisibleHint(true);
    super.onActivityCreated(savedInstanceState);
}
```We invoke it proactively setUserVisibleHint Control first not called setUserVisibleHint Method issues, but setUserVisibleHint Method will take precedence onCreateView Method call when onCreateView Method is called again setUserVisibleHint Method, then we want to call the onCreateView Method for tagging judgment





<div class="se-preview-section-delimiter"></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

/** 
*Flag bit, flag has been initialized
*/ 
private boolean isPrepared;

/** 
* The first fragemnt to process calls the first fragment setUserVisibleHint(true); the method, because setUserVisibleHint(true); the method is called only when it is switched, so the first one is displayed first when initializing,
*But setUserVisibleHint prefers the onCreate method to just think, which causes null pointer problems, so use tags to remember whether initialization is complete and then request data when it is done.
* @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; //Initialized
Log.d(this.getClass().getSimpleName(), "onCreateView"); 
return view; 

@Override 
public void setUserVisibleHint(boolean isVisibleToUser) { 
super.setUserVisibleHint(isVisibleToUser);

if (isPrepared && isVisibleToUser) {//Visible and loaded after initialization
Log.d(this.getClass().getSimpleName(), "Request data");
}


"`

/**
 * Flag bit, flag has been initialized
 */
private boolean isPrepared;


/**
 * The first fragemnt is to be processed, calling the first fragment setUserVisibleHint(true); the method, because setUserVisibleHint(true); the method is called only when it is switched, so when initializing, let the first show first.
 * But setUserVisibleHint takes precedence over the onCreate method just because it has a null pointer problem, so use markup to remember if initialization is complete and request data when it is done
 * @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;//Initialized
    Log.d(this.getClass().getSimpleName(), "onCreateView");
    return view;
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    if (isPrepared && isVisibleToUser) {//Visible and loaded after initialization
    Log.d(this.getClass().getSimpleName(), "Request data");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

Code address: https://github.com/jiangshujing/FragmentDemo.git

Posted by Fari on Mon, 01 Jul 2019 09:39:29 -0700