IllegalStateException当更换一个片段

这是使用兼容包的小型Android 2.2testing应用程序。 这是(当然是错误的),我试图在接受点击时replace片段。 我试图用相同片段类的新(不同)实例来replace它。 正如我将解释它不按预期工作,我需要帮助:

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 ”和“ rightLand ”,如果单击片段“ leftLand ”的button,则它会更改创build一个新的片段,并用另一个片段replace“ rightLand ”片段实例相同的FragamentActivity类的实例。 使这两个实例不同的参数是传递给“newInstance(int)”的参数,它基于点击的button。

纵向 :

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

在纵向方向,它只显示片段“ leftPort ”(与“ leftLand ”具有相同的布局),如果你点击它的button,然后启动一个意图启动RightFragmentActivity,显示片段“ rightLand

它工作正常…如果我不replace正确的片段。 如果我这样做(单击横向button),然后在随后的方向更改(重新启动活动) 的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 

我意识到旧的“ 右翼片段在被取代之后不会被破坏。 这可能是我错误的方法来取代它的结果。

任何帮助将非常感激。

提前致谢!

/天使Galindo穆尼奥斯

我想你可能误解了我的意见,所以我会在这里提供更详细的解释。

删除或replace片段时通常会遇到的一个问题是试图通过XML删除已添加到布局的片段,而不是通过Java编程。 这与在片段的Java代码的onCreateView()函数中扩展片段自己的布局不同(这是您在回应我的评论时似乎要描述的内容)。 为了说明我在说什么,我会告诉你两种方法,人们试图删除/replace片段。

这是错误的做法:

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)在我之前提到的讨论中所说的话。

这是正确的做法(至less在我的经验):

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(); } 

该策略不会在初始布局中添加片段。 而是在创buildActivity时将其添加到Java代码中。 这使它可以从布局中remove()使用remove()replace()

这可能无法解决你的问题,但碎片创build是一个普遍的困难。 您可以确保以正确的方式添加碎片以便将其移除,如果这样不能解决问题,则可以进一步进行故障排除。

还有另一种方法,当你正在开发大屏幕平板电脑的应用程序时,你可以为每个屏幕方向膨胀diferents布局。你只需要创build两个布局,并用纵向或横向命名它们,在onCreate它只需根据方向。

在onClick事件中,只需使用getResources()。getConfiguration()。orientation来标识方向

并做你的东西