替换 Fragment 时出现 IllegalStateException

2024-02-15

它是使用兼容性包的小型 Android 2.2 测试应用程序。这是我在收到点击时尝试替换片段的(当然是错误的)方法。我试图用同一 Fragment 类的新(不同)实例替换它。正如我将解释的那样,它无法按预期工作,我需要帮助:

public class MainFragmentActivity extends FragmentActivity {
  ...

  public void myAction(View view) {
    ...
    RightFragment newRightFrag = RightFragment.newInstance(myNewOption);
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
    ft.replace(R.id.landscape_right_fragment, newRightFrag);
    ft.commit();
  }
}

你一定会看到我的错误是什么。无论如何,让我们对应用程序应该做什么进行更多解释:

景观方向:

---------                ----------
| L | R |  -> click ->   | L | R2 |
---------                ----------

在横向方向上,该活动有一个包含 2 个片段的视图:“leftLand“&”右岸”,如果您单击片段的按钮“leftLand“然后它会更改创建一个新的片段并替换“右岸" Fragment 实例与同一 FragamentActivity 类的另一个实例。这两个实例的不同之处在于传递给“newInstance(int)”的参数,它基于单击的按钮。

纵向 :

-----                  -----
|   |                  |   |
| L |   -> click ->    | R |
|   |                  |   |
-----                  -----

在纵向方向上,它只显示片段“leftPort“(与“具有相同的布局leftLand”),如果您单击它的按钮,它会启动一个 Intent 并启动右侧的 FragmentActivity,其中显示 Fragment “右岸"

它工作正常......如果我不替换正确的片段。如果我这样做(单击横向按钮),然后进行后续方向更改(重新启动活动)FragmentActivity 无法启动,因为“IllegalStateException: Fragment RightFragment did not create a view"像这样 :

D/AndroidRuntime( 1428): Shutting down VM
W/dalvikvm( 1428): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
E/AndroidRuntime( 1428): FATAL EXCEPTION: main
E/AndroidRuntime( 1428): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.agm.test/com.agm.test.MainFragmentActivity}: android.view.InflateException: Binary XML file line #13: Error inflating class fragment
E/AndroidRuntime( 1428):        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
E/AndroidRuntime( 1428):        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
E/AndroidRuntime( 1428):        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3815)
E/AndroidRuntime( 1428):        at android.app.ActivityThread.access$2400(ActivityThread.java:125)
E/AndroidRuntime( 1428):        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2037)
E/AndroidRuntime( 1428):        at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 1428):        at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 1428):        at android.app.ActivityThread.main(ActivityThread.java:4627)
E/AndroidRuntime( 1428):        at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 1428):        at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 1428):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
E/AndroidRuntime( 1428):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
E/AndroidRuntime( 1428):        at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 1428): Caused by: android.view.InflateException: Binary XML file line #13: Error inflating class fragment
E/AndroidRuntime( 1428):        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:582)
E/AndroidRuntime( 1428):        at android.view.LayoutInflater.rInflate(LayoutInflater.java:618)
E/AndroidRuntime( 1428):        at android.view.LayoutInflater.inflate(LayoutInflater.java:407)
E/AndroidRuntime( 1428):        at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
E/AndroidRuntime( 1428):        at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
E/AndroidRuntime( 1428):        at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:198)
E/AndroidRuntime( 1428):        at android.app.Activity.setContentView(Activity.java:1647)
E/AndroidRuntime( 1428):        at com.agm.test.MainFragmentActivity.onCreate(MainFragmentActivity.java:25)
E/AndroidRuntime( 1428):        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
E/AndroidRuntime( 1428):        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
E/AndroidRuntime( 1428):        ... 12 more
E/AndroidRuntime( 1428): Caused by: java.lang.IllegalStateException: Fragment com.agm.test.RightFragment did not create a view.
E/AndroidRuntime( 1428):        at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:287)
E/AndroidRuntime( 1428):        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:558)
E/AndroidRuntime( 1428):        ... 21 more
W/ActivityManager(   59):   Force finishing activity com.agm.test/.MainFragmentActivity

我意识到,老“右片段” 被替换后并没有被破坏。这可能是我试图替换它的错误方法造成的结果。

任何帮助将非常感激。

提前致谢!

/ 安吉尔·加林多·穆尼奥斯


我认为您可能误解了我的评论,因此我将在这里提供更详细的解释。

删除或替换片段时经常出现的一个问题是尝试删除通过 XML(而不是在 Java 中以编程方式)添加到布局的片段。这是not与在中扩展片段自己的布局相同onCreateView()片段的 Java 代码的函数(这似乎是您在对我的评论的回复中描述的内容)。为了说明我正在谈论的内容,我将向您展示人们尝试删除/替换片段的两种方法。

这是错误的做法:

XML 布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <fragment android:name="com.example.ExampleFragment"
    android:id="@+id/example_fragment"
    android:layout_weight="1"
    android:layout_width="0dp"
    android:layout_height="match_parent" />

</LinearLayout>

Java:

swapFragment()
{
    Fragment newFragment = new ExampleFragment();
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    transaction.replace(R.id.fragment_container, newFragment);
    transaction.addToBackStack(null);
    transaction.commit();
}

该代码不会按照您期望的方式执行。添加到 XML 布局中的初始片段不会被删除。这是因为 XML 布局旨在描述静态布局元素。您可以在运行时更改它们的内容,或隐藏它们,但无法从布局中删除这些内容。这就是黛安·哈克伯恩 (Dianne Hackborn) 在讨论话题 http://groups.google.com/group/android-developers/browse_thread/thread/b56967e0f147168d?pli=1我之前链接过。

这是正确的方法(至少根据我的经验):

XML 布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <!-- Fragment will go here eventually, but it's not added in the layout -->

</LinearLayout>

Java:

protected void onCreate(Bundle savedInstanceState)
{
     super.onCreate(savedInstanceState);
     setContentView(R.layout.my_layout);

     ExampleFragment newFragment = new ExampleFragment();
     FragmentTransaction transaction = getFragmentManager().beginTransaction();
     transaction.add(R.id.fragment_container, newFragment);
     transaction.commit();
}

...

swapFragment()
{
    Fragment newFragment = new ExampleFragment();
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    transaction.replace(R.id.fragment_container, newFragment);
    transaction.addToBackStack(null);
    transaction.commit();
}

该策略不会在初始布局中添加片段。相反,它会在创建 Activity 时将其添加到 Java 代码中。这允许将其从布局中删除(使用remove() or replace())

这可能无法解决您的问题,但这是片段造成的常见困难。您可以确保以正确的方式添加片段以允许它们被删除,然后如果这不能解决问题,我们可以进一步排除故障。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

替换 Fragment 时出现 IllegalStateException 的相关文章

随机推荐