我遇到过Android中嵌套片段的问题。 当我旋转屏幕时,嵌套片段以某种方式存活。 我想出了一个示例来说明这个问题。
public class ParentFragment extends BaseFragment
{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_parent, container);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getChildFragmentManager()
.beginTransaction()
.add(getId(), new ParentFragmentChild(), ParentFragmentChild.class.getName())
.commit();
}
@Override
public void onResume() {
super.onResume();
log.verbose("onResume(), numChildFragments: " + getChildFragmentManager().getFragments().size());
}
}
public class ParentFragmentChild extends BaseFragment
{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_child, null);
}
}
BaseFragment只记录方法调用。 这就是我在旋转屏幕时看到的内容。
ParentFragment﹕ onAttach(): ParentFragment{420d0a98 #0 id=0x7f060064}
ParentFragment﹕ onCreate()
ParentFragment﹕ onViewCreated()
ParentFragmentChild﹕ onAttach(): ParentFragmentChild{420d08d0 #0 id=0x7f060064 com.kinoteatr.ua.filmgoer.test.ParentFragmentChild}
ParentFragmentChild﹕ onCreate()
ParentFragmentChild﹕ onViewCreated()
ParentFragment﹕ onResume()
ParentFragment﹕ onResume(), numChildFragments: 1
ParentFragmentChild﹕ onResume()
ParentFragmentChild﹕ onPause()
ParentFragment﹕ onPause()
ParentFragment﹕ onSaveInstanceState()
ParentFragmentChild﹕ onSaveInstanceState()
ParentFragmentChild﹕ onStop()
ParentFragment﹕ onStop()
ParentFragmentChild﹕ onDestroyView()
ParentFragment﹕ onDestroyView()
ParentFragmentChild﹕ onDestroy()
ParentFragmentChild﹕ onDetach()
ParentFragment﹕ onDestroy()
ParentFragment﹕ onDetach()
ParentFragment﹕ onAttach(): ParentFragment{4211bc38 #0 id=0x7f060064}
ParentFragment﹕ onCreate()
ParentFragmentChild﹕ onAttach(): ParentFragmentChild{420f4180 #0 id=0x7f060064 com.kinoteatr.ua.filmgoer.test.ParentFragmentChild}
ParentFragmentChild﹕ onCreate()
ParentFragment﹕ onViewCreated()
ParentFragmentChild﹕ onViewCreated()
ParentFragmentChild﹕ onAttach(): ParentFragmentChild{42132a08 #1 id=0x7f060064 com.kinoteatr.ua.filmgoer.test.ParentFragmentChild}
ParentFragmentChild﹕ onCreate()
ParentFragmentChild﹕ onViewCreated()
ParentFragment﹕ onResume()
ParentFragment﹕ onResume(), numChildFragments: 2
ParentFragmentChild﹕ onResume()
ParentFragmentChild﹕ onResume()
ParentFragmentChild﹕ onPause()
ParentFragmentChild﹕ onPause()
ParentFragment﹕ onPause()
ParentFragment﹕ onSaveInstanceState()
ParentFragmentChild﹕ onSaveInstanceState()
ParentFragmentChild﹕ onSaveInstanceState()
ParentFragmentChild﹕ onStop()
ParentFragmentChild﹕ onStop()
ParentFragment﹕ onStop()
ParentFragmentChild﹕ onDestroyView()
ParentFragmentChild﹕ onDestroyView()
ParentFragment﹕ onDestroyView()
ParentFragmentChild﹕ onDestroy()
ParentFragmentChild﹕ onDetach()
ParentFragmentChild﹕ onDestroy()
ParentFragmentChild﹕ onDetach()
ParentFragment﹕ onDestroy()
ParentFragment﹕ onDetach()
ParentFragment﹕ onAttach(): ParentFragment{42122a48 #0 id=0x7f060064}
ParentFragment﹕ onCreate()
ParentFragmentChild﹕ onAttach(): ParentFragmentChild{420ffd48 #0 id=0x7f060064 com.kinoteatr.ua.filmgoer.test.ParentFragmentChild}
ParentFragmentChild﹕ onCreate()
ParentFragmentChild﹕ onAttach(): ParentFragmentChild{420fffa0 #1 id=0x7f060064 com.kinoteatr.ua.filmgoer.test.ParentFragmentChild}
ParentFragmentChild﹕ onCreate()
ParentFragment﹕ onViewCreated()
ParentFragmentChild﹕ onViewCreated()
ParentFragmentChild﹕ onViewCreated()
ParentFragmentChild﹕ onAttach(): ParentFragmentChild{42101488 #2 id=0x7f060064 com.kinoteatr.ua.filmgoer.test.ParentFragmentChild}
ParentFragmentChild﹕ onCreate()
ParentFragmentChild﹕ onViewCreated()
ParentFragment﹕ onResume()
ParentFragment﹕ onResume(), numChildFragments: 3
ParentFragmentChild﹕ onResume()
ParentFragmentChild﹕ onResume()
ParentFragmentChild﹕ onResume()
他们不断增加。有谁知道为什么会这样?
答案 0 :(得分:6)
当我旋转屏幕时,嵌套片段会以某种方式存活。
他们生存的原因与ParentFragment
幸存的相同,即使你不存在
使用setRetainInstance()
保留实例。 FragmentManager
就是这个原因,
在这种情况下,ChildFragmentManager
ParentFragment
用于处理嵌套片段。
您需要了解的一些事项:
FragmentManager
负责管理片段和
将它们添加到活动的视图层次结构中。FragmentManager
处理两件事:
Fragment Transactions
。FragmentManager
询问片段时
view id(findFragmentById
),如果片段已经在列表中,
FragmentManager
将返回它。然后你可以使用它。最初显示活动时
由于应用程序刚刚启动,因此每个片段只有一个实例。其中一个ParentFragment
和ParentFragmentChild
之一。到目前为止一切都很好。
屏幕旋转#1
此时,活动的FragmentManager
和ParentFragment的ChildFragmentManager
会保存其片段列表。然后,您可以看到两个片段是如何完全被破坏的。
重新创建活动时,新的FragmentManager
将检索列表并且
重新创建列出的片段,使其在方向更改之前完成所有内容。请注意,这些是不同的实例,这些是由Android重新创建的新片段(这就是为什么你没有空构造函数就有片段,Android需要它来重新创建片段)。
现在,这是ParentFragment
:
getChildFragmentManager()
.beginTransaction()
.add(getId(), new ParentFragmentChild(), ParentFragmentChild.class.getName())
.commit();
您并未尝试查明ChildFragmentManager
列表中是否已有ParentFragmentChild
(已有)。这就是你可以看到两个片段被创建的原因,第一个是由ChildFragmentManager
重新创建的,第二个是由前面的代码创建的。
屏幕旋转#2
在第二个方向更改之前,ChildFragmentManager列表中有两个ParentChildFragment
,它们被重新创建,另外一个由代码创建。
最好使用FragmentManager
重新创建的片段,而不是创建新片段。