Android – 片段.replace()不会replace内容 – 放在最上面

活动:

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" /> 

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

当我点击后,第一个片段得到正确显示(没有第二个),但最初都是可见的(我只希望最后一个可见)。

我在这里错过了什么?

你在这里做了两件事:

  1. 您无法replace静态放置在xml布局文件中的片段。 您应该在布局中创build一个容器(例如一个FrameLayout ),然后使用FragmentTransaction以编程方式添加FragmentTransaction

  2. FragmentTransaction.replace需要包含片段的容器的id而不是片段的id作为第一个参数。 所以你应该传递第一个参数作为你添加第一个片段的容器的id。

你可以参考这个链接了解更多细节。

我有一个类似的问题,但我的问题是,我正在使用两个不同的片段pipe理器:一个来自getSupportFragmentManager()和一个来自getFragmentManager()。 如果我用SupportFragmentManager添加了一个片段,然后尝试用FragmentManagerreplace这个片段,那么这个片段就会被添加到最上面。 我需要更改代码,以便使用相同的FragmentManager,并处理该问题。

android开发人员网站build议使用FrameLayout在运行时dynamic加载片段。 你已经在xml文件中硬编码了这个片段。 所以它不能在运行时被删除,就像这个链接中提到的那样:

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

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

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

在更换碎片之前,您可以清除backStack:

  FragmentManager fm = getActivity().getSupportFragmentManager(); for (int i = 0; i < fm.getBackStackEntryCount(); i++) { fm.popBackStack(); } // replace your fragments 

我有同样的问题,看到了所有的答案,但没有一个包含我的错误! 在尝试replace当前片段之前,我在容器活动的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"> 

我同意Sapan Diwakar的回答。 但是我已经find了解决办法。

首先,在你的activity(例如activity_main ),你有所有的布局,添加一个FrameLayout 。 它的高度和宽度应该match parent 。 另外,给它一个id

现在,在要replace当前布局的片段中,调用onPause()onResume() 。 在View初始化所有的内部容器。 并将其visibility设置为onResume()onPause()visibility

:不是你用这个片段replace的FrameLayout

假设你在ViewPagerViewPagerTabLayoutImageView和一个自定义的<fragment> 。 如上所述添加一个FrameLayout

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

示例代码:

在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); } 

快乐的编码!

谢谢Sapan Diwakar等人。 这个答案帮助了我。 我简单地创build了一个没有内部片段的RelativeLayout,使用RelativeLayout作为父视图或组视图,在事务中指定该组视图进行replace,并且工作。

代码:getSupportFragmentManager()。beginTransaction().replace(R.id.content_group_view,itemDetailFragment).commit();

布局:

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

使用容器而不是使用片段

 <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”或“原始”的实现,不要混合它们。 我遇到了这个问题,因为我混合了他们。

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

 transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); 

在Oncreate()

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

现在这将永远是你的默认片段…如果你在xml布局中添加片段,它将总是重叠,所以在运行时设置片段的初始内容

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

  1. 采取框架布局,你正在取代你的片段

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

     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(); 

如果你想要整个例子,我会给你发个简单的评论……