2013-02-21 87 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

相关问题