Android:使用支持片段管理器时复制片段
我对碎片有一个非常奇怪的问题。我使用最新的支持库。我还使用与 Google 在其 IOSCHED 项目
但我在旋转后重新创建活动时遇到问题。销毁并再次创建活动后,我调用管理片段事务的方法(在 onStart 方法中)。该行仅被调用一次,但它创建了两次片段!
这是我的活动方法:
public abstract class SinglePaneActivity extends FragmentActivity
{
@Override
protected void onStart()
{
super.onStart();
if(mFragment == null)
{
mFragment = onCreatePane();
mFragment.setArguments(Utils.intentToFragmentArguments(getIntent()));
Log.w(TAG, "Fragment creation counter = " + createCounter);
createCounter++;
getSupportFragmentManager()
.beginTransaction()
.add(R.id.root_container,mFragment)
.commit();
}
}
@Override
protected void onStop()
{
Log.i(TAG, "onStop");
if(mFragment != null)
{
getSupportFragmentManager()
.beginTransaction()
.remove(mFragment)
.commit();
mFragment = null;
}
super.onStop();
}
}
和我的日志:
--Start of application--
11-18 13:26:37.050: I/SinglePaneActivity(19040): onCreate
11-18 13:26:37.050: I/SinglePaneActivity(19040): onStart
11-18 13:26:37.055: W/SinglePaneActivity(19040): replacing fragment, counter = 1
11-18 13:26:37.075: I/MyFragment(19040): onCreate
11-18 13:26:37.110: I/MyFragment(19040): onActivityCreated
--Rotating the device--
11-18 13:26:39.600: I/SinglePaneActivity(19040): onStop
11-18 13:26:39.600: I/SinglePaneActivity(19040): onDestroy
11-18 13:26:39.605: I/MyFragment(19040): onDestroy
11-18 13:26:39.755: I/MyFragment(19040): onCreate
11-18 13:26:39.755: I/SinglePaneActivity(19040): onCreate
11-18 13:26:39.790: I/MyFragment(19040): onActivityCreated
11-18 13:26:39.800: I/SinglePaneActivity(19040): onStart
11-18 13:26:39.800: W/SinglePaneActivity(19040): replacing fragment, counter = 2
11-18 13:26:39.810: I/MyFragment(19040): onCreate
11-18 13:26:39.815: I/MyFragment(19040): onActivityCreated
--Rotating the device back--
11-18 13:36:47.060: I/SinglePaneActivity(19040): onStop
11-18 13:36:47.060: I/SinglePaneActivity(19040): onDestroy
11-18 13:36:47.060: I/MyFragment(19040): onDestroy
11-18 13:36:47.065: I/MyFragment(19040): onDestroy
11-18 13:36:47.130: I/MyFragment(19040): onCreate
11-18 13:36:47.130: I/MyFragment(19040): onCreate
11-18 13:36:47.130: I/SinglePaneActivity(19040): onCreate
11-18 13:36:47.140: I/MyFragment(19040): onActivityCreated
11-18 13:36:47.150: I/MyFragment(19040): onActivityCreated
11-18 13:36:47.150: I/SinglePaneActivity(19040): onStart
11-18 13:36:47.150: W/SinglePaneActivity(19040): replacing fragment, counter = 3
11-18 13:36:47.160: I/MyFragment(19040): onCreate
11-18 13:36:47.160: I/MyFragment(19040): onActivityCreated
--Exiting the app--
11-18 13:36:48.880: I/SinglePaneActivity(19040): onStop
11-18 13:36:48.885: I/SinglePaneActivity(19040): onDestroy
11-18 13:36:48.885: I/MyFragment(19040): onDestroy
11-18 13:36:48.890: I/MyFragment(19040): onDestroy
11-18 13:36:48.890: I/MyFragment(19040): onDestroy
因此每次旋转后片段的数量都会增加。
旋转后,它会在进入我的 onStart 方法之前恢复片段,并且我的 onStart 方法在同一 Frame 布局容器中创建第二个相同的片段。但它在哪里恢复第一个片段呢?我想禁止它。或者我应该更改我的“if”来测试它是否已经创建?但我不知道如何确定它。看来空测试是没有用的。
我还通过用 replace()
替换 add()
方法做了一些小解决方法。之后,片段的数量不再增长,并且在 onStart
方法创建新片段之前每个片段都会被销毁。但这在一些片段中造成了严重的问题,我在他们的 onCreate 方法中启动了一些后台进程...
请帮助我...我真的不知道该怎么办。非常感谢您的任何建议或想法!
I have a very weird issue with fragments. I use the newest support library. I also use similar code as is used by Google in their IOSCHED project
But I have problem with recreating of activity after rotation. After an activity is destroyed and created again, I call methods for managing the fragment transaction (in onStart method). This line is called only once, but it creates the fragment TWICE !
This is my activity method:
public abstract class SinglePaneActivity extends FragmentActivity
{
@Override
protected void onStart()
{
super.onStart();
if(mFragment == null)
{
mFragment = onCreatePane();
mFragment.setArguments(Utils.intentToFragmentArguments(getIntent()));
Log.w(TAG, "Fragment creation counter = " + createCounter);
createCounter++;
getSupportFragmentManager()
.beginTransaction()
.add(R.id.root_container,mFragment)
.commit();
}
}
@Override
protected void onStop()
{
Log.i(TAG, "onStop");
if(mFragment != null)
{
getSupportFragmentManager()
.beginTransaction()
.remove(mFragment)
.commit();
mFragment = null;
}
super.onStop();
}
}
and my logs:
--Start of application--
11-18 13:26:37.050: I/SinglePaneActivity(19040): onCreate
11-18 13:26:37.050: I/SinglePaneActivity(19040): onStart
11-18 13:26:37.055: W/SinglePaneActivity(19040): replacing fragment, counter = 1
11-18 13:26:37.075: I/MyFragment(19040): onCreate
11-18 13:26:37.110: I/MyFragment(19040): onActivityCreated
--Rotating the device--
11-18 13:26:39.600: I/SinglePaneActivity(19040): onStop
11-18 13:26:39.600: I/SinglePaneActivity(19040): onDestroy
11-18 13:26:39.605: I/MyFragment(19040): onDestroy
11-18 13:26:39.755: I/MyFragment(19040): onCreate
11-18 13:26:39.755: I/SinglePaneActivity(19040): onCreate
11-18 13:26:39.790: I/MyFragment(19040): onActivityCreated
11-18 13:26:39.800: I/SinglePaneActivity(19040): onStart
11-18 13:26:39.800: W/SinglePaneActivity(19040): replacing fragment, counter = 2
11-18 13:26:39.810: I/MyFragment(19040): onCreate
11-18 13:26:39.815: I/MyFragment(19040): onActivityCreated
--Rotating the device back--
11-18 13:36:47.060: I/SinglePaneActivity(19040): onStop
11-18 13:36:47.060: I/SinglePaneActivity(19040): onDestroy
11-18 13:36:47.060: I/MyFragment(19040): onDestroy
11-18 13:36:47.065: I/MyFragment(19040): onDestroy
11-18 13:36:47.130: I/MyFragment(19040): onCreate
11-18 13:36:47.130: I/MyFragment(19040): onCreate
11-18 13:36:47.130: I/SinglePaneActivity(19040): onCreate
11-18 13:36:47.140: I/MyFragment(19040): onActivityCreated
11-18 13:36:47.150: I/MyFragment(19040): onActivityCreated
11-18 13:36:47.150: I/SinglePaneActivity(19040): onStart
11-18 13:36:47.150: W/SinglePaneActivity(19040): replacing fragment, counter = 3
11-18 13:36:47.160: I/MyFragment(19040): onCreate
11-18 13:36:47.160: I/MyFragment(19040): onActivityCreated
--Exiting the app--
11-18 13:36:48.880: I/SinglePaneActivity(19040): onStop
11-18 13:36:48.885: I/SinglePaneActivity(19040): onDestroy
11-18 13:36:48.885: I/MyFragment(19040): onDestroy
11-18 13:36:48.890: I/MyFragment(19040): onDestroy
11-18 13:36:48.890: I/MyFragment(19040): onDestroy
So the number of fragments is growing after each rotation.
After rotation it restores the fragment before it goes to my onStart method and my onStart method creates second same fragment in same Frame layout container. But WHERE it restores the first fragment ? I want to forbit it. Or should I change my "if" to test if it is already created? But I dont know how to determine it. It looks that null test is useless.
I also made small workaround by replacing add()
method by replace()
. After that, the number of fragments isn't growing and each fragment is destroyed before new one is in onStart
method created. But this makes serious problem in some fragments where I start some background processes in theirs onCreate method...
Please help me...I really have no idea what to do with it. Thank you very much for any advice or idea !
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好吧,我找到了解决方案。我必须使用片段管理器将代码从 onStart 移动到 onCreate 并检查
savedInstanceState
的null
值。好吧,我不知道它会自动从savedInstanceState
保存和恢复。很高兴知道!编辑:
为了完全正确地做到这一点,即当savedInstanceState不为空时恢复片段,应该有:
Well I found a solution. I had to move the code with fragment manager from onStart to onCreate and check
null
value ofsavedInstanceState
. Well I didn't know that it is saved and restored fromsavedInstanceState
automagically. Good to know!EDIT:
And to do it completely correct, i.e. restore fragment when savedInstanceState is not null, there should be:
我遇到了类似的问题,但我从父片段添加子片段并看到重复的子片段。我试图将其添加到父片段的
onStart
中,以便我可以访问父视图,而该视图在onCreate
中不可用。因此,我没有将代码移至onCreate
,而是将其移至onActivityCreated
;该方法可以访问父视图,还可以访问savedInstanceState变量来检查片段是否已经被自动添加。从活动添加片段时这不是问题,因为活动的视图在onCreate
中可用。如果由于某种原因您需要在
onStart
或savedInstanceState
不可用的其他位置添加片段,这里有一个替代方案。使用问题中的原始 onStart 代码......您可以
替换
而不是添加
片段:然后,如果片段已经自动添加,您的新片段将只需在视图中替换它即可。
I had a similar problem, but I was adding a child fragment from a parent fragment and seeing a duplicate child fragment. I was trying to add it in
onStart
of the parent fragment so I could access the parent view, which isn't available inonCreate
. So instead of moving the code toonCreate
, I moved it toonActivityCreated
; that method has access to the parent view and also has access to thesavedInstanceState
variable to check if the fragment is already being added automatically. This isn't a problem when adding a fragment from an activity because the activity's view is available inonCreate
.If for some reason you need to add a fragment in
onStart
or another place wheresavedInstanceState
is not available, here's an alternative. Using the original onStart code from the question......you could
replace
rather thanadd
the fragment:Then if the fragment was already added automatically, your new fragment will just replace it in the view.
或者,如果您的片段不在返回堆栈中:
setRetainInstance(true);
Or if your fragment doesn't in back stack:
setRetainInstance(true);