Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
Activity + Fragment page overlap problem
Today, I encountered a strange problem. Our software is composed of Activity + Fragment. In some scenarios, we even found the phenomenon of overlapping fragments.
First, the cause of the problem
Root cause: The Activity is destroyed and recreated, but the already loaded Fragmen are saved, and new fragments are created when the Activity is recreated, so it overlaps.
Problem scenario:
-
Switching between horizontal and vertical screens
-
Resume the page after an error
-
The Activity is destroyed when memory runs out
Delve deeper into why this happens in vertical and horizontal screens?
I found a sympathetic explanation online:
When we rotate the screen, the activity is destroyed and recreated, and the onSaveInstanceState(Bundle outState) method is executed before the destruction. This method will save some information about the activity, including the added fragment. When the activity is recreated, the variable in the fragment will be initialized. Clicking the navigation at the bottom will add the fragment again, leading to the problem of overlapping.
Second, solutions
To simulate this scenario, go to the mobile developer options -> Apps -> Do not Keep the Activity simulation scenario.
Solution 1:
The state is not saved when the Activity is recycled, so that the view is reloaded when the Activity is destroyed and reentered
@Override
protected void onSaveInstanceState(Bundle outState) {
// super.onSaveInstanceState(outState);
}
Copy the code
Solution 2:
-
Create a collection of fragments and load the Fragment during initialization
-
When displaying fragments, add a tag to each Fragment
-
The Fragment is removed from the Bundle in the onCreate of the Activity and replaced with the corresponding Fragment in the collection
-
Hide other fragments while displaying them
-
If you want to record the Fragment index before saving
private void showFragment(int position) {
mCurrentFragPosition = position;
}
Copy the code
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("position", mCurrentFragPosition);
}
Copy the code
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState ! = null) { mCurrentFragPosition = savedInstanceState.getInt("position"); / / restore collapse before the position of the fragments fragments fragments = mFragmentManager. FindFragmentByTag + mCurrentFragPosition (" "); if (fragment ! = null) mFragments[mCurrentFragPosition] = fragment; }}Copy the code