110

活动:

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

Fragment1 fragment = new Fragment1();
Fragment2 fragment2 = new Fragment2();

transaction.replace(R.id.Fragment1, fragment);
transaction.addToBackStack(null);
transaction.commit();

FragmentTransaction transaction2 = getSupportFragmentManager().beginTransaction();
transaction2.replace(R.id.Fragment1, fragment2);
transaction2.addToBackStack(null);
transaction2.commit();

视图中的代码:

<fragment
    android:id="@+id/Fragment1"
    android:name="com.landa.fragment.Fragment1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_below="@+id/include1" /> 

问题是,内容并没有真正被替换 - 它被放在顶部(所以它重叠)。

当我单击返回时,第一个片段会正确显示(没有第二个片段),但最初两者都是可见的(我只希望最后一个片段可见)。

我在这里想念什么?

4

16 回答 16

148

你在这里做错了两件事:

  1. 您不能替换静态放置在xml布局文件中的片段。您应该在布局中创建一个容器(例如 a FrameLayout),然后使用FragmentTransaction.

  2. FragmentTransaction.replace期望包含片段的容器的 id 而不是片段的 id 作为第一个参数。因此,您应该将第一个参数作为您添加第一个片段的容器的 id 传递。

您可以参考此链接了解更多详情。

于 2013-02-11T10:50:13.427 回答
33

我有一个类似的问题,但我的问题是我使用了两个不同的片段管理器:一个getSupportFragmentManager()来自getFragmentManager(). 如果我添加了一个片段,SupportFragmentManager然后尝试用 替换片段FragmentManager,则片段将被添加到顶部。我需要更改代码以便使用相同的代码FragmentManager并解决问题。

于 2014-05-27T20:47:03.183 回答
17

android 开发者网站建议使用 aFrameLayout在运行时动态加载片段。您已在 xml 文件中对片段进行硬编码。所以它不能在运行时被删除,如此链接中提到的:

http://developer.android.com/training/basics/fragments/creating.html

此链接显示如何通过您的程序添加片段:

http://developer.android.com/training/basics/fragments/fragment-ui.html

于 2013-02-11T10:50:55.827 回答
7

我有同样的问题,看到了所有的答案,但没有一个包含我的错误!在尝试替换当前片段之前,我在容器活动的 xml 中显示了默认片段,如下所示:

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

    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="....ShopFragment"
        android:id="@+id/fragment"
        tools:layout="@layout/fragment_shop" />
</FrameLayout>

在那之后,虽然我把它传递FrameLayout给了,fragmentTransaction.replace()但我遇到了确切的问题。它显示了前一个片段之上的第二个片段。

通过从 xml 中删除片段并onCreate()在容器活动的方法中以编程方式显示它来解决问题,以便在程序启动时进行默认预览,如下所示:

    fragmentTransaction = getFragmentManager().beginTransaction();
    fragmentTransaction.replace(R.id.fragment_frame_layout,new ShopFragment());
    fragmentTransaction.addToBackStack(null);
    fragmentTransaction.commit();

和容器活动 xml:

<FrameLayout
    android:id="@+id/fragment_frame_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
于 2016-08-22T14:23:03.810 回答
5

您可以在替换片段之前清除 backStack:

    FragmentManager fm = getActivity().getSupportFragmentManager();

    for (int i = 0; i < fm.getBackStackEntryCount(); i++) {
        fm.popBackStack();
    }

    // replace your fragments
于 2013-02-11T10:47:29.693 回答
3
<FrameLayout
    android:id="@+id/fragment_frame_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?android:windowBackground">
//Add fragment here
</FrameLayout>

添加android:background="?android:windowBackground">到您的片段所在的容器中。就我而言,我添加了一个FrameLayout,这应该会有所帮助。

于 2019-11-19T10:59:32.217 回答
1

我同意 Sapan Diwakar 的回答。但我找到了如何做到这一点的解决方法。

activity_main首先,在您拥有所有布局的活动(例如)中,添加一个FrameLayout. 它的高度和宽度应该是match parent. 另外,给它一个id.

现在,在要替换当前布局的片段中,调用onPause()and onResume()。初始化所有内部容器View。并将它们设置visibilityGONEinonResume()VISIBLEinonPause()

注意:不是FrameLayout你用这个片段替换的那个。

假设您有ViewPager、和TabLayout中的ImageView自定义<fragment>activity_main.xml添加,FrameLayout如上所述。

abcFragment.java,在onClick()函数中,添加addToBackstack(null)transaction

示例代码:

在 xyzFragment 中,它将替换 abcFragment(以及 activity_main.xml 中显示的所有内容),执行此操作

@Override
    public void onResume() {
        super.onResume();

    // On resume, make everything in activity_main invisible except this fragment.
    slidingTabs = getActivity().findViewById(R.id.sliding_tabs);
    viewPager = getActivity().findViewById(R.id.pager);
    miniPlayerFragment = getActivity().findViewById(R.id.mini_pager);

    slidingTabs.setVisibility(View.GONE);
    viewPager.setVisibility(View.GONE);
    miniPlayerFragment.setVisibility(View.GONE);
}

@Override
public void onPause() {
    super.onPause();

    // Make everything visible again
    slidingTabs = getActivity().findViewById(R.id.sliding_tabs);
    viewPager = getActivity().findViewById(R.id.pager);
    miniPlayerFragment = getActivity().findViewById(R.id.mini_pager);

    slidingTabs.setVisibility(View.VISIBLE);
    viewPager.setVisibility(View.VISIBLE);
    miniPlayerFragment.setVisibility(View.VISIBLE);
}

快乐编码!

于 2015-09-16T17:33:23.563 回答
1

使用容器而不是使用片段

<FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="Hello World!" />

现在在 MainActivity

if(condition)
    getFragmentManager().beginTransaction().replace(R.id.container,new FirstFragment()).commit();                    
else
    getFragmentManager().beginTransaction().replace(R.id.container, new SecondFragment()).commit();

请注意,您的片段类应导入“android.app.Fragment”确保您使用“support.v4”或“原始”实现,不要混合使用它们。我遇到了这个问题,因为我混合了它们。

于 2016-02-22T06:50:04.703 回答
0

感谢 Sapan Diwakar 和其他人。这个答案帮助了我。我只是创建了一个没有片段的RelativeLayout,将RelativeLayout用作父视图或组视图,在事务中指定要替换的组视图,它就可以工作了。

代码:

getSupportFragmentManager().beginTransaction()
                            .replace(R.id.content_group_view, itemDetailFragment).commit();

XML:

 <RelativeLayout
         android:id="@+id/content_group_view"
         android:layout_width="match_parent"
         android:layout_height="match_parent">

 </RelativeLayout>
于 2015-10-21T22:29:31.463 回答
0

您可以使用 FragmentTransaction 中的 setTransition 方法来修复重叠问题。

transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
于 2016-05-06T15:29:59.147 回答
0

在 Oncreate()

  BaseFragmentloginpage fragment = new BaseFragmentloginpage();
            android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.frame, fragment);
            fragmentTransaction.isAddToBackStackAllowed();
            fragmentTransaction.commit();

现在这将始终是您的默认片段...如果您在 xml 布局中添加片段,它将始终重叠,因此在运行时使用片段设置初始内容

于 2017-02-16T08:49:41.713 回答
0

使用此问题解决后我遇到了同样的问题

  1. 在你替换你的片段的地方进行框架布局

    <FrameLayout
                    android:id="@+id/fragment_place"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />
    
  2. 和替换代码

    public void selectFrag(View view) {
    Fragment fr;
    
      if(view == findViewById(R.id.button2))
    {
         fr = new FragmentTwo();
    
     }else {
         fr = new FragmentOne();
     }
     FragmentManager fm = getFragmentManager();
     FragmentTransaction fragmentTransaction = fm.beginTransaction();
     fragmentTransaction.replace(R.id.fragment_place, fr);
     fragmentTransaction.commit();
    

如果您想要整个示例,我将发送给您,只需评论我......

于 2017-04-06T07:05:50.070 回答
0

我也有同样的问题,但这是因为我没有改变我试图添加到我的框架布局的片段的背景颜色。

尝试这样做,layout_heightlayout_width设置为match_parent

于 2018-06-04T15:05:16.647 回答
0

我曾经遇到过这个问题,发现是因为我不小心删除了android:background您的 xml 代码中缺少的属性。我相信它就像你在粉刷墙壁时一样,android:background是墙壁的颜色,而其他视图则放置在该基础颜色之上。当您在定位视图之前不绘制墙壁时,它们将位于该墙壁中已经存在的内容之上,在您的情况下,您的另一个片段。不知道对你有没有帮助,祝你好运。

于 2019-07-04T22:55:58.897 回答
0

我已经尝试过所有情况并尝试解决问题但仍然没有得到解决方案。我不知道为什么它不适合我。我同意上述答案,因为很多人都同意。

我只是在扩展答案,下面是对我有用的方式。

我已将此属性添加android:clickable="true"到文件的顶部父布局中fragment.xml

我希望有人能得到帮助。

于 2019-10-18T12:08:45.030 回答
0

检查您的框架布局 ID 并将其替换如下

fragmentTransactionChange = MainActivity.this.getSupportFragmentManager().beginTransaction();
fragmentTransactionChange.replace(R.id.progileframe, changeFragment);
fragmentTransactionChange.addToBackStack(null);
fragmentTransactionChange.commit();
于 2020-08-05T09:13:53.663 回答