2014-03-29 61 views
9

我想在FragmentActivity内的v4支持库的Fragment中使用FragmentTabHost。这个异常在调试时抛出在Activity OnCreate中,因为Alex已经指出了可能的条件,但仍然在oncreate活动中提交片段事务。由于这个例外,我的活动显示带有标签的空tabcontent。java.lang.IllegalStateException:在创建活动时在FragmentTabHost中的onSaveInstanceState后无法执行此操作

注意: - 1)我锁定了屏幕旋转 - 无方向条件。 2)这发生在初始状态下的活动oncreate中 3)我在Activity OnCreate()中使用了commit() 4)作为日志点,提交关系在TabHost中完成,而不是从我这边完成。

这里是我的日志: -

03-29 11:32:55.975: E/AndroidRuntime(27470): java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1343) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1361) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.support.v4.app.FragmentTabHost.onAttachedToWindow(FragmentTabHost.java:282) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.view.View.dispatchAttachedToWindow(View.java:9924) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2198) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2206) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2206) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2206) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2206) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2206) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.view.ViewGroup.dispatchAttachedToWindow(ViewGroup.java:2206) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1079) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2585) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.os.Handler.dispatchMessage(Handler.java:99) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.os.Looper.loop(Looper.java:137) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at android.app.ActivityThread.main(ActivityThread.java:4507) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at java.lang.reflect.Method.invokeNative(Native Method) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at java.lang.reflect.Method.invoke(Method.java:511) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557) 
03-29 11:32:55.975: E/AndroidRuntime(27470): at dalvik.system.NativeStart.main(Native Method) 

这是我的代码

活动:有FragmentTabHost

private void addFragmentToStack(int originCurrentSplitNo, boolean isOrgin, 
      int holderId) { 

     // Instantiate a new fragment(FragmentTabhost as the layout of this). 
     SplitFragment newFragment = SplitFragment.newInstance(); 


     // Add the fragment to the activity, pushing this transaction 
     // on to the back stack. 
     FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
     ft.replace(holderId, (Fragment) newFragment, 
       newFragment.getCurrentFragmentTag()); 
     if (null == fragmentTagHolder) { 
      fragmentTagHolder = new ArrayList<String>(); 
     } 
    //tag holders in the activity 
     fragmentTagHolder.add(newFragment.getCurrentFragmentTag()); 
     ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
     ft.addToBackStack(null); 
     ft.commit(); 
    } 

片段将被附加到活动

//SplitFragment.java

private View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     if (container == null) { 
      // Currently in a layout without a container, so no 
      // reason to create our view. 
      return null; 
     } 


     View fragmentTabHostView = inflater.inflate(R.layout.fragment_tab_host_layout, container, 
       false); 
     initFrgmentTab(fragmentTabHostView); 
     return fragmentTabHostView; 
    } 

    private View initFrgmentTab(View oemView) { 
     if (null == fragmentTabHostView) { 
      return null; 
     } 

     typeViewHost = (FragmentTabHost) fragmentTabHostView 
       .findViewById(android.R.id.tabhost); 

     if (!(null == typeViewHost)) { 

      typeViewHost.setup(getActivity().getApplicationContext(), getChildFragmentManager(),android.R.id.tabcontent); 

      LinkedHashMap<Integer, fragmentTabContent> frgmentTabContent = ((OEMCarInspectionActivity) getActivity()) 
        .getfrgmentTabContent Details(); 
    Set<Integer> views = frgmentTabContent .getKeySet(); 
    //Creating the tabs 
      for (Integer viewCode : views) { 
       fragmentTabContent carView = carTypeViews.get(viewCode); 
       String tabTitle = fragmentTabContent.getViewDescription(); 

       if (null == tabTitle || tabTitle .trim().isEmpty()) { 
        continue; 
       } 
       Bundle tabViewBundle = new Bundle(); 
       carViewBundle.putInt(CarViewFragment.CARVIEW_CODE_KEY, 
         viewCode); 
       typeViewHost.addTab(typeViewHost.newTabSpec(tabTitle) 
         .setIndicator(tabTitle), TabViewFragment.class, 
         tabViewBundle); 

      } 
} 

片段以充当tabcontent为FragmentTabHost:FragmentTabHost的

//TabViewFragment.java 
/** 
    * The Fragment's UI is just a simple text view showing its instance number. 
    */ 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     if (null == container) { 
      // Currently in a layout without a container, so no 
      // reason to create our view. 
      return null; 
     } 

     View v = inflater.inflate(R.layout.tab_view_layout, container, 
       false); 

     return v; 
    } 

布局:

//fragment_tab_host_layout.xml(layout for SplitFragment.java) 

<?xml version="1.0" encoding="utf-8"?> 
<android.support.v4.app.FragmentTabHost 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@android:id/tabhost" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:orientation="vertical" > 

     <LinearLayout 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:layout_weight="0" 
      android:orientation="vertical" > 


      <HorizontalScrollView 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content" 
       android:fillViewport="true" 
       android:scrollbars="none" > 

       <TabWidget 
        android:id="@android:id/tabs" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:orientation="horizontal" /> 
      </HorizontalScrollView> 
     </LinearLayout> 

     <RelativeLayout 
      android:layout_width="fill_parent" 
      android:layout_height="0dp" 
      android:layout_weight="1" > 

      <FrameLayout 
       android:id="@android:id/tabcontent" 
       android:layout_width="0dp" 
       android:layout_height="0dp" /> 
     </RelativeLayout> 
    </LinearLayout> 

</android.support.v4.app.FragmentTabHost> 
+1

显示您的代码。 – Piyush

回答

0

原本我以为这是最有可能的旋转问题。但有了更多的细节,我想我会看到这个问题。

您正在初始化片段onCreateView中的tabhost。在onCreateView中,片段尚未添加到活动中;它只是提供它的布局。很可能会话状态尚未恢复(就片段事务管理器而言),因为它基本上处于的状态状态(插入视图)的中间。

尝试将您的tabhost init代码移动到onActivityCreated中,该代码在插入视图后调用。 即:

private View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     if (container == null) { 
      // Currently in a layout without a container, so no 
      // reason to create our view. 
      return null; 
     } 


     View fragmentTabHostView = inflater.inflate(R.layout.fragment_tab_host_layout, container, 
       false); 

     return fragmentTabHostView; 
    } 

public void onActivityCreated (Bundle savedInstanceState) { 
     initFrgmentTab(getView()); 
} 

如果仍然抛出嘘声像万能,在尝试将其移动到的onResume(这是后状态肯定已经恢复)。

+0

Thnxs的答复,我想我以前没有提供所有的信息,但现在我已经与附注一起更新。 – user3475098

+0

“快速”修复将使用“ft.commitAllowingStateLoss();”而不是“ft.commit();”但我怀疑这种方法会有潜在的问题。 –

+0

它只会避免抛出异常,但不会解决问题。但是,如何通过TabHost和内部tabhost引发异常并执行ft.commit()。 – user3475098

0

我有一个解决方案:

  1. 复制FragmentTabHost的所有代码。
  2. 在你的项目中一类新的贴吧,并命名为MyTabHost
  3. 更换所有的提交()在代码中commitAllowStateLoss()
  4. 使用这个类 - MyTabHost在您的项目,而不是FragmentTabHost。

这是丑陋的地狱,但它的作品。

相关问题