为什么会出现fragment重叠现象:
1
2
因为activity内存回收的时候,fragment被FragmentManager保存了下来,当再次创建Activity的时候,原来被保存下来的fragment默认为显示状态
解决方式: 1. fragment保存显隐状态 2. activity重新创建的时候通过 tag找到原来fragment并重新设置显隐状态
FragmentPagerAdapter和FragmentStatePagerAdapter
- FragmentPagerAdapter内fragment当移除视野外之后不会重新创建,会保存在内存中
- FragmentStatePagerAdapter 当fragment移除视野之外就会销毁
fragmentTransaction.add(containerViewId, fragment, tagId).commitAllowingStateLoss()
并不会立刻将 frament 添加到 FragmentManager 中,所以在这之后调用FragmentManager.findFragmentByTag 是找不到fragment。走过一个Handler周期就可以通过FragmentManager.findFragmentByTag获取到了。具体解决方法可以参考 Glide 添加 SupportRequestManagerFragment 的方式
ViewPager2 + Fragment
FragmentStateAdapter
- 从 0 Fragment 开始向左滑动一点 就会开始创建 1 Fragment 生命周期会走到 onStart,并不会执行 onResume。只有继续向左滑动当前显示Fragment 变为 1 的时候,才会执行 1 的 onResume 方法,并且 0 Fragment执行 onPaused 方法
- 多次左右切换并不会重新创建 Fragment 只会执行 onResume 和 onPaused 方法
ViewPager + Fragment
Fragment + BottomBar
- Fragment 使用 hide 和 show 的方式控制显隐
- Fragment的生命周期和 Activity 生命周期同步。
- 左右切换的时候会调用 FragmentManager.hideFragment 和 FragmentManager.showFragment 改变 Fragment.mHidden 的值,但是不会执行 onResume onPaused onStart onStop 等生命周期方法
理解 Fragment 的生命周期
FragmentManager
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
void moveToState(@NonNull Fragment f, int newState) {
FragmentStateManager fragmentStateManager = mFragmentStore.getFragmentStateManager(f.mWho);
if (fragmentStateManager == null) {
fragmentStateManager = new FragmentStateManager(mLifecycleCallbacksDispatcher, f);
fragmentStateManager.setFragmentManagerState(Fragment.CREATED);
}
newState = Math.min(newState, fragmentStateManager.computeMaxState());
if (f.mState <= newState) {
switch (f.mState) {
case Fragment.INITIALIZING:
if (newState > Fragment.INITIALIZING) {
if (isLoggingEnabled(Log.DEBUG)) Log.d(TAG, "moveto ATTACHED: " + f);
fragmentStateManager.attach(mHost, this, mParent);
}
// fall through
case Fragment.ATTACHED:
if (newState > Fragment.ATTACHED) {
fragmentStateManager.create();
}
// fall through
case Fragment.CREATED:
if (newState > Fragment.CREATED) {
fragmentStateManager.createView(mContainer);
fragmentStateManager.activityCreated();
fragmentStateManager.restoreViewState();
}
// fall through
case Fragment.ACTIVITY_CREATED:
if (newState > Fragment.ACTIVITY_CREATED) {
fragmentStateManager.start();
}
// fall through
case Fragment.STARTED:
if (newState > Fragment.STARTED) {
fragmentStateManager.resume();
}
}
} else if (f.mState > newState) {
switch (f.mState) {
case Fragment.RESUMED:
if (newState < Fragment.RESUMED) {
fragmentStateManager.pause();
}
// fall through
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
fragmentStateManager.stop();
}
// fall through
case Fragment.ACTIVITY_CREATED:
if (newState < Fragment.ACTIVITY_CREATED) {
FragmentAnim.AnimationOrAnimator anim = null;
if (f.mView != null && f.mContainer != null) {
// Stop any current animations:
f.mContainer.endViewTransition(f.mView);
f.mView.clearAnimation();
if (!f.isRemovingParent()) {
ViewGroup container = f.mContainer;
View view = f.mView;
container.removeView(view);
if (container != f.mContainer) {
return;
}
}
}
destroyFragmentView(f);
}
// fall through
case Fragment.CREATED:
if (newState < Fragment.CREATED) {
fragmentStateManager.destroy(mHost, mNonConfig);
}
// fall through
case Fragment.ATTACHED:
if (newState < Fragment.ATTACHED) {
fragmentStateManager.detach(mNonConfig);
}
}
}fff
}