IllegalStateException异常与Android的碎片 [英] IllegalStateException with Android Fragments

查看:234
本文介绍了IllegalStateException异常与Android的碎片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有,我想通过隐藏和显示交换两个片段的画面(不可以替换他们)被点击某个视图时。这里是我的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 RadioButtons. This produces two FragmentTransactions, 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆