Fragment Transaction上的片段重复

时间:2011-03-14 01:31:06

标签: android transactions android-fragments

好的,每当我尝试替换我的应用程序中的片段时,它只会将容器内部的片段添加到另一个片段中,并保留当前片段。我试过调用replace并引用包含片段的视图,并引用片段本身。这些都不奏效。我可以使用片段事务管理器将一个片段添加到视图中,但即使我尝试在添加它之后将其删除,它也不起作用。任何帮助,将不胜感激。这是我的档案。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    //Setup the actionabar. Use setDrawableBackground to set a background image for the actionbar.
    final ActionBar actionbar = getActionBar();
    actionbar.setDisplayShowTitleEnabled(false);
    actionbar.setDisplayUseLogoEnabled(true);
    actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    actionbar.addTab(actionbar.newTab().setText(R.string.home_tab_text).setTabListener(this),true);
    actionbar.addTab(actionbar.newTab().setText(R.string.insert_tab_text).setTabListener(this));

    Fragment fragment = new insert_button_frag();
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    transaction.replace(R.id.button_fragment, fragment);
    transaction.addToBackStack(null);

    transaction.commit();
}

这是布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <LinearLayout
        android:orientation="vertical"
        android:id="@+id/button_fragment_container"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >

        <fragment
            android:name="com.bv.silveredittab.home_button_frag"
            android:id="@+id/button_fragment"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />

    </LinearLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <fragment
            android:name="com.bv.silveredittab.quick_insert_frag"
            android:id="@+id/quick_insert_frag"
            android:layout_width="350dip"
            android:layout_height="fill_parent" />

        <fragment
            android:name="com.bv.silveredittab.editor_frag"
            android:id="@+id/editor_frag"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />

    </LinearLayout>

</LinearLayout>

这是片段代码

public class insert_button_frag extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        return inflater.inflate(R.layout.insert_buttons,container, false);
    }
}
像我说的那样。我已经尝试引用片段父视图来替换它,片段本身(通过id)仍然只是添加新片段,在原始片段所在的包含视图中。

4 个答案:

答案 0 :(得分:33)

我通过在Layout中使用占位符然后在运行时将片段附加到它来解决了这个问题。

和你一样,如果我在我的xml布局中实例化我的Fragment,那么在运行时将其替换为另一个Fragment之后内容将保持可见。

答案 1 :(得分:18)

问题在于这一行:

transaction.replace(R.id.button_fragment, fragment);

replace有两个重载表单。在这两个中,第一个参数是要替换的片段的容器,而不是片段本身。因此,在您的情况下,您需要致电

transaction.replace(R.id.button_fragment_container, fragment);

编辑:我在你的问题中看到你已经试过了两个。我已经测试并验证了这种行为。这似乎是FragmentTransaction API中的一个错误。

Edit2:毕竟不是一个bug。您根本无法替换布局文件中静态添加的片段。您只能替换以编程方式添加的内容(Android: can't replace one fragment with another

答案 2 :(得分:2)

我有同样的问题。请看一下这个链接:Android Fragment Duplication

我想知道你是否将容器传递给inflater.inflate()方法会导致它在旧的片段内创建新片段而不是批量替换。我一直在工作版本中为我的inflaters提供'null'。

以下是我工作的版本的基本要点......

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
   View newFrag = new View(getActivity().getApplicationContext());
   newFrag = inflater.inflate(R.id.frag, null);
   return newFrag;
}

答案 3 :(得分:0)

google developer guide非常混乱,因为它首先显示在你的xml中实现硬编码片段。但是如果你真的想用新的片段替换现有的片段,那么你应该在运行时添加它(第一个)。

official site状态是什么

FragmentTransaction replace(int containerViewId,Fragment fragment,String tag)

  

替换添加到容器的现有片段。这是   与当前所有人调用remove(Fragment)基本相同   添加了使用相同containerViewId添加的片段   add(int,Fragment,String)与此处给出的参数相同。

你应该注意到它说添加的现有片段替换为容器

所以,你的xml应该是这样的 someActivity.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    tools:context="someActivity">

    <ImageView
        .../>

    <LinearLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="bottom"/>

</RelativeLayout>

而在 OnCreate()

中的活动
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        [...]
        getSupportFragmentManager().beginTransaction()
                .add(R.id.fragment_container, new FirstFragment).commit();

    }

您可以轻松地将片段替换为动画,并将事件添加到后台,以便保存其状态。

private SecondFrag getSecondFrag(){
    if(secondFrag == null)
        secondFrag = new SecondFrag()
    return secondFrag;
}

private void openRechargeFragment(){
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.setCustomAnimations(R.anim.show_frag, R.anim.hide_frag,
                R.anim.show_frag, R.anim.hide_frag);
        ft.replace(R.id.fragment_container, getSecondFrag(), "myTAG");
        ft.addToBackStack(null);
        ft.commit();
}