preface
While writing a ViewPager2 article, I noticed that the latest Fragment code had eliminated the setUserVisibleHint method in favor of the setMaxLifecycle method, which means to set the maximum life cycle. It is not possible to set the life cycle of Fragment directly. It is necessary to intervene indirectly through add, attach, remove, detach, show and hide methods. This function is intended to briefly introduce the principle and effect of setMaxLifecycle.
Reading Guide:
- This article is based on
Androidx 1.1.0 - alpha07
Version of thefragment
Carry on, also supportsetMaxLifecycle
Minimum version of - This article will be based on
FragmentPagerAdapter
forsetMaxLifecycle
Example Application Explanation
Basic introduction
SetMaxLifecycle is defined within the FragmentTransaction in parallel with the add, attach, remove, detach, show, hide methods;
FragmentTransaction
public FragmentTransaction setMaxLifecycle(@NonNull Fragment fragment,
@NonNull Lifecycle.State state) {
addOp(new Op(OP_SET_MAX_LIFECYCLE, fragment, state));
return this;
}
Copy the code
Parameter interpretation:
fragment
That’s the Fragment object that you want to operate on, and that’s the prerequisitefragment
Must have been added toFragmentManager
;state
Lifecycle.State
Enumeration type, which can be used only if it is at leastLifecycle.State.CREATED
, otherwise, submitted to theIllegalArgumentException
abnormal
There are five states at Lifecycle. The minimum requirement is lifecycle.state. CREATED, so the available parameters are CREATED, STARTED, RESUMED, State and Lifecycle.
Life cycle status understanding
In the Fragment, there are five states defined. The State is not as described above in Lifecycle.State, but the logic is basically the same;
INITIALIZING
The initial stateCREATED
Created StatusACTIVITY_CREATED
Fully created, but not startedSTARTED
Create and start, but cannot be performedRESUMED
Create is up and operational
This article only explains the three states: CREATED, STARTED, and RESUMED. Since mState and Lifecycle.State defined in Fragment are not the same, they are considered the same concept in this article.
Corresponds to the life cycle
I’m sure you all know that the Fragment lifecycle has onDestory, onStop and other methods, but there are not so many states, so how to identify the state and the corresponding relationship, the corresponding relationship is given below;
First, I treat the lifecycle methods from onCreate->onCretateView->onStart->onResume->onPause->onStop-> onDestoryView->onDestory as ordering from small to large;
Similarly, we consider the life cycle state CREATED->STARTED->RESUMED to rank from small to large;
CREATED a state
CREATED refers to the CREATED state. In a narrow sense, the lifecycle method goes to onCreate. If the current fragment state is greater than CREATED, then the lifecycle method goes to onDestoryView. So there are two cases of CREATED;
STARTED state
If the fragment’s status is greater than STARTED, the fragment’s life cycle method goes to onPause. If the fragment’s status is less than CREATED, the fragment’s life cycle method goes to onStart.
The RESUMED state
RESUMED indicates a special state, which only represents the onResume state. No matter how big or small, it eventually stays in the onResume state.
The above life-cycle state torsion conclusions are based onFragmentManagerImpl.moveToState()
Method extraction, if misleading, please advise
How to use
SetMaxLifecycle can be used alone or in combination with add and other methods. First, we analyze the state changes when add is executed separately:
Perform the add operation separately
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_layout,cardFragment);
fragmentTransaction.commit();
Copy the code
Add cooperate setMaxLifecycle (Lifecycle. State. CREATED)
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_layout,cardFragment);
fragmentTransaction.setMaxLifecycle(cardFragment, Lifecycle.State.CREATED);
fragmentTransaction.commit();
Copy the code
Add cooperate setMaxLifecycle (Lifecycle. State. STARTED)
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_layout,cardFragment);
fragmentTransaction.setMaxLifecycle(cardFragment, Lifecycle.State.STARTED);
fragmentTransaction.commit();
Copy the code
Add cooperate setMaxLifecycle (Lifecycle. State. RESUMED)
FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
fragmentTransaction.add(R.id.frame_layout,cardFragment);
fragmentTransaction.setMaxLifecycle(cardFragment, Lifecycle.State.RESUMED);
fragmentTransaction.commit();
Copy the code
Use setMaxLifecycle alone
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setMaxLifecycle(cardFragment, xxx);
fragmentTransaction.commit();
Copy the code
- right
RESUMED
Status of the Fragment to perform operationsCREATED
operation
- right
RESUMED
Status of the Fragment to perform operationsSTARTED
operation
- right
RESUMED
Status of the Fragment to perform operationsCREATED
Operation, in progressSTARTED
operation
For space reasons, I don’t want to cover all the combinations. As long as you understand the life cycle states, whether they are up or down, whether they are combined or used alone, you can control them.
FragmentPagerAdapter changes
Since setMaxLifecycle introduces the life cycle setting and replaces the old setUserVisibleHint method, it is also adapted in the FragmentPagerAdapter
FragmentPagerAdapter
public static final int BEHAVIOR_SET_USER_VISIBLE_HINT = 0;
public static final int BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT = 1;
private final int mBehavior;
public FragmentPagerAdapter(@NonNull FragmentManager fm) {
this(fm, BEHAVIOR_SET_USER_VISIBLE_HINT);
}
public FragmentPagerAdapter(@NonNull FragmentManager fm,@Behavior int behavior) {
mFragmentManager = fm;
mBehavior = behavior;
}
Copy the code
The latest FragmentPagerAdapter uses an mBehavior to control either setUserVisibleHint or setMaxLifecycle. MBehavior is specified in the constructor;
Replace setUserVisibleHint(false) with setMaxLifecycle(mCurrentPrimaryItem, Lifecycle.state.started) Replace setUserVisibleHint(true) with setMaxLifecycle(fragment, Lifecycle.state.resumed);
Why should lifecy.state.started be used? Add +Lifecycle.State.STARTED and attach+Lifecycle.
The end result is an invisible Fragment that only goes through the life cycleonStart
Method, won’t goonResume
Methods;
The new scheme is lazily loaded
In the past, we used setUserVisibleHint to control lazy Fragment loading. In the latest version of FragmentPagerAdapter, we can switch the BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT mode. In FragmentonResume, more display logic;
To switch to the BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT mode, the BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT mode is BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT mode.
new FragmentPagerAdapter(getSupportFragmentManager(),FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)
Copy the code
conclusion
What does this article actually say? Let’s summarize:
Use setMaxLifecycle to further control the lifecycle of the Fragment. This is a supplement to add, attach, and other commands.
Secondly, this function can be used in the official control, improving the use experience of ViewPager+Fragment, lazy loading attention points;
Finally encourage everyone (mainly their own) to look at the source code, tamp the foundation, can not change should be the end of this article.