IllegalStateException异常与Android的碎片 [英] IllegalStateException with Android Fragments
问题描述
我有,我想通过隐藏和显示交换两个片段的画面(不可以替换他们)被点击某个视图时。这里是我的code:
...
私人片段currentFragment;
...
私人无效swapFragment(片段片段){
FragmentTransaction英尺= getChildFragmentManager()调用BeginTransaction()。 如果(currentFragment =空&放大器;!&放大器;!currentFragment.isHidden()){
ft.hide(currentFragment);
} 如果(!fragment.isAdded()){
ft.add(R.id.fragment_holder,片段);
}其他{
ft.show(片段);
}
ft.commit(); currentFragment =片段;
}
...
R.id.fragment_holder
是的FrameLayout。我不声明任何<片断>
在我的布局标签。本来我的Swap方法只是这...
getChildFragmentManager()调用BeginTransaction()取代(R.id.fragment_holder,片段).commit()。
...但对于原因,我不会进入这里,我想要做的显示/隐藏,而不是替代。
按道理这应该是pretty简单:如果有一个片段放映,首先将其隐藏。如果是这样显示的片段首次,添加它,否则显示它。然后保存当前片段。
问题是第一次启动,这坠毁与 IllegalStateException异常
说明该片段已添加。
八月11日至12日:36:49.098:E / AndroidRuntime(27293):致命异常:主要
八月11日至12日:36:49.098:E / AndroidRuntime(27293):了java.lang.RuntimeException:无法启动活动ComponentInfo {com.my.package / com.my.package.activities.MainActivity}:java.lang.IllegalStateException :片段已经补充说:ContactFragment {42263030#0 ID = 0x7f0a006d}
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2324)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2374)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.app.ActivityThread.access $ 600(ActivityThread.java:154)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1248)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.os.Handler.dispatchMessage(Handler.java:99)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.os.Looper.loop(Looper.java:137)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.app.ActivityThread.main(ActivityThread.java:5242)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在java.lang.reflect.Method.invokeNative(本机方法)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在java.lang.reflect.Method.invoke(Method.java:511)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:799)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在dalvik.system.NativeStart.main(本机方法)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):java.lang.IllegalStateException:产生的原因片段已经补充说:ContactFragment {42263030#0 ID = 0x7f0a006d}
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1175)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.support.v4.app.BackStackRecord.run(BackStackRecord.java:616)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1460)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.support.v4.app.Fragment.performStart(Fragment.java:1499)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:957)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1086)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.support.v4.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:1882)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:573)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在com.my.package.activities.MainActivity.onStart(MainActivity.java:252)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1164)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.app.Activity.performStart(Activity.java:5233)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2287)
八月11日至12日:36:49.098:E / AndroidRuntime(27293):... 11个
因此,原来我的交换逻辑的作品就好。这个问题实际上是一些与 RadioGroup中
在其中的 OnCheckChangedListener
可以为其子女间的单一支票变化两次调用单选
秒。这将产生两个 FragmentTransaction
S,其中第二个导致IllegalStateException异常,因为它试图添加一个已经加入片段。
对我来说,解决办法是添加
如果(片段== currentFragment)回报;
之初 swapFragment()
。
I have a screen where I want to swap two fragments by hiding and showing (not replacing them) when certain views are clicked. Here is my code:
...
private Fragment currentFragment;
...
private void swapFragment(Fragment fragment) {
FragmentTransaction ft = getChildFragmentManager().beginTransaction();
if (currentFragment != null && !currentFragment.isHidden()) {
ft.hide(currentFragment);
}
if (!fragment.isAdded()) {
ft.add(R.id.fragment_holder, fragment);
} else {
ft.show(fragment);
}
ft.commit();
currentFragment = fragment;
}
...
R.id.fragment_holder
is a FrameLayout. I do not declare any <fragment>
tags in my layout. Originally my swap method was simply this...
getChildFragmentManager().beginTransaction().replace(R.id.fragment_holder, fragment).commit();
...but for reasons I won't get into here I want to do show/hide instead of replace.
Logically this should be pretty straightforward: if there's a fragment showing, hide it first. If it's the first time showing this fragment, add it, otherwise show it. Then save the current fragment.
The problem is on first launch, this crashed with an IllegalStateException
stating the fragment has already been added.
11-12 08:36:49.098: E/AndroidRuntime(27293): FATAL EXCEPTION: main
11-12 08:36:49.098: E/AndroidRuntime(27293): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.my.package/com.my.package.activities.MainActivity}: java.lang.IllegalStateException: Fragment already added: ContactFragment{42263030 #0 id=0x7f0a006d}
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2324)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2374)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.app.ActivityThread.access$600(ActivityThread.java:154)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1248)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.os.Handler.dispatchMessage(Handler.java:99)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.os.Looper.loop(Looper.java:137)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.app.ActivityThread.main(ActivityThread.java:5242)
11-12 08:36:49.098: E/AndroidRuntime(27293): at java.lang.reflect.Method.invokeNative(Native Method)
11-12 08:36:49.098: E/AndroidRuntime(27293): at java.lang.reflect.Method.invoke(Method.java:511)
11-12 08:36:49.098: E/AndroidRuntime(27293): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:799)
11-12 08:36:49.098: E/AndroidRuntime(27293): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
11-12 08:36:49.098: E/AndroidRuntime(27293): at dalvik.system.NativeStart.main(Native Method)
11-12 08:36:49.098: E/AndroidRuntime(27293): Caused by: java.lang.IllegalStateException: Fragment already added: ContactFragment{42263030 #0 id=0x7f0a006d}
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1175)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:616)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1460)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.support.v4.app.Fragment.performStart(Fragment.java:1499)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:957)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1086)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.support.v4.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:1882)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:573)
11-12 08:36:49.098: E/AndroidRuntime(27293): at com.my.package.activities.MainActivity.onStart(MainActivity.java:252)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1164)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.app.Activity.performStart(Activity.java:5233)
11-12 08:36:49.098: E/AndroidRuntime(27293): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2287)
11-12 08:36:49.098: E/AndroidRuntime(27293): ... 11 more
So it turns out my swapping logic works just fine. The problem is actually something with RadioGroup
in which it's OnCheckChangedListener
can be called twice for a single check change among its child RadioButton
s. This produces two FragmentTransaction
s, the second of which causes the IllegalStateException because it tries to add an already added fragment.
The solution for me was to add
if (fragment == currentFragment) return;
at the beginning of swapFragment()
.
这篇关于IllegalStateException异常与Android的碎片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!