2013-02-21 83 views
0

我有一個使用帶有選項卡的ActionBar的SherlockFragmentActivity。其中一個選項卡是SherlockFragment,其中包含一個包含片段的佈局文件。首次顯示該標籤時,一切都很棒。如果我切換到另一個選項卡,然後回到那個標籤,我得到一個崩潰:包含片段的ActionBar選項卡重新顯示時崩潰

02-21 10:25:10.077: E/AndroidRuntime(3916): Caused by: java.lang.IllegalArgumentException: Binary XML file line #29: Duplicate id 0x7f06006e, tag null, or parent id 0x0 with another fragment for com.nexapps.myq.fragments.TitleInfo 02-21 10:25:10.077: E/AndroidRuntime(3916): at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:275) 02-21 10:25:10.077: E/AndroidRuntime(3916): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:676) 02-21 10:25:10.077: E/AndroidRuntime(3916): ... 21 more

我的主要活動:

public class TitleActivity extends SherlockFragmentActivity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) {  
     ... 
     actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
     ... 
     Tab tab = actionBar.newTab().setText(R.string.details); 
     tab.setTabListener(new TabListener<TitleDetailsFragment>(this, "details", TitleDetailsFragment.class)); 
     actionBar.addTab(tab);   
    } 

} 

選項卡監聽器: 公共類TabListener實現com.actionbarsherlock。 app.ActionBar.TabListener {0}私人片段mFragment; private final Activity mActivity; private final String mTag; private final Class mClass;

public TabListener(Activity activity, String tag, Class<T> cls) { 
     mActivity = activity; 
     mTag = tag; 
     mClass = cls; 
    } 

    public TabListener(Activity activity, String tag, Class<T> clz, Fragment fragment) { 
     mActivity = activity; 
     mTag = tag; 
     mClass = clz; 
     mFragment = fragment; 
    } 

    public void onTabSelected(Tab tab, FragmentTransaction ft) { 
     if (mFragment == null) { 
      mFragment = Fragment.instantiate(mActivity, mClass.getName()); 
      ft.add(android.R.id.content, mFragment, mTag); 
     } else { 
      ft.attach(mFragment); 
     } 

     TabChangeInterface tci = (TabChangeInterface) mActivity; 
     if (tci != null) { 
     tci.tabSelect(mTag); 
     } 
    } 

    public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
     if (mFragment != null) { 
      ft.detach(mFragment); 
     } 
    } 

    public void onTabReselected(Tab tab, FragmentTransaction ft) { 
    } 

}

我的標籤片段:

public class TitleDetailsFragment extends SherlockFragment { 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.activity_title, container, false); 
     return view; 
    } 
} 

R.layout.activity_title:

<fragment 
    android:id="@+id/info" 
    android:name="foo.TitleInfo" 
    ... 

我可以刪除ID(其中修復該問題),但這些幫助隨着狀態的變化。有關如何保持ID並解決問題的任何想法?

回答

-1

所以這與選項卡內容是一個片段和片段不能包含片段的事實有關。所以在這裏使用視圖或手動刪除/添加使用事務。

+2

這個答案實際上是不正確的。這些標籤在技術上屬於操作欄的一部分。這些片段是完全獨立的,除非您通過製作片段選項卡來創建自己的自定義選項卡。此外,你可以將碎片嵌入碎片,但它確實使事情成爲PITA。 – Matt 2013-02-22 03:17:00

0

不能刪除嵌入到xml佈局中的片段。對於這一點,你需要改變你的XML包括<FrameLayout android:id="fragment_container" .../>然後以編程方式通過調用替換幀中的片段:

MyFrag newFragment = new MyFrag(); 
FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
ft.replace(R.id.fragment_container,newFragment,"myFragName") 
.addToBackStack("myFragName")//optional 
.commit(); 

假設你正在使用支持包,否則你只需要改變getSupportFragmentManager()getFragmentManager()

而且您可以在此處詳細瞭解使用片段:http://developer.android.com/training/basics/fragments/index.html

編輯:更新基於新的信息

R.layout.activity_title包括代碼:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context=".Title" > 

    <FrameLayout 
     android:id="@+id/fragment_container" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" /> 
</LinearLayout> 

TitleActivity.class:

public class TitleActivity extends SherlockFragmentActivity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_title);   
     ... 
     actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
     ... 
     Tab tab = actionBar.newTab().setText(R.string.details); 
     tab.setTabListener(new TabListener<TitleDetailsFragment>(this, "details", TitleDetailsFragment.class)); 
     actionBar.addTab(tab);   
    } 

} 

R.layout.details_fragment:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_vertical|center_horizontal" 
     android:textSize="10sp" 
     android:textStyle="italic" 
     android:text="Details are here!"/> 
</RelativeLayout> 

TabFragment:

public class TitleDetailsFragment extends SherlockFragment { 

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.details_fragment, container, false); 
    } 
} 

TabListener你可以保持相同的代碼上面。

+0

我的代碼不會替換任何片段。除非你的意思是基類是? – user910046 2013-02-21 20:10:59

+0

對不起,我誤解了你的問題。既然你已經編譯了你的代碼,如果你現在把'@ + id'改成'@id',它應該可以工作。 – Matt 2013-02-21 20:27:30

+0

然後我得到「資源未找到」,它不會重新編譯。看起來onCreateView被調用時,已經有一個仍然活動與相同的ID – user910046 2013-02-21 20:51:25

相關問題