2014-03-29 53 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。

這是醜陋的地獄,但它的作品。

相關問題