活动:
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" />
问题是,内容并没有真正被替换 - 它被置于顶部(因此它重叠)。
当我单击后退时,第一个片段会正确显示(没有第二个片段),但最初两个片段都是可见的(我只希望最后一个片段可见)。
我在这里缺少什么?
答案 0 :(得分:127)
你在做错两件事:
您无法替换静态放置在xml
布局文件中的片段。您应该在布局中创建一个容器(例如FrameLayout
),然后使用FragmentTransaction
以编程方式添加该片段。
FragmentTransaction.replace
期望包含片段的容器的id而不是片段的id作为第一个参数。所以你应该将第一个参数作为你添加第一个片段的容器的id传递给。
您可以参考this link了解更多详情。
答案 1 :(得分:25)
我有类似的问题,但我的问题是我使用了两个不同的Fragment管理器:
一个来自getSupportFragmentManager()
,一个来自getFragmentManager()
。如果我使用SupportFragmentManager
添加了一个片段,然后尝试使用FragmentManager
替换片段,则片段将被添加到顶部。我需要更改代码,以便使用相同的FragmentManager
并处理问题。
答案 2 :(得分:14)
android开发者网站建议使用FrameLayout
在运行时动态加载片段。您已在xml文件中对片段进行了硬编码。所以它不能在运行时删除,如此链接中所述:
http://developer.android.com/training/basics/fragments/creating.html
此链接显示如何通过您的程序添加片段:
http://developer.android.com/training/basics/fragments/fragment-ui.html
答案 3 :(得分:6)
我有同样的问题,看到了所有的答案,但没有一个包含我的错误! 在尝试替换当前片段之前,我在容器活动的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()
方法中以编程方式显示该问题,以便在程序开头执行默认预览,如下所示: < / p>
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">
答案 4 :(得分:3)
您可以在替换片段之前清除backStack:
FragmentManager fm = getActivity().getSupportFragmentManager();
for (int i = 0; i < fm.getBackStackEntryCount(); i++) {
fm.popBackStack();
}
// replace your fragments
答案 5 :(得分:0)
我同意Sapan Diwakar的回答。但我找到了解决方法,如何做到这一点。
首先,在您拥有所有布局的活动中(例如activity_main
),添加FrameLayout
。它的高度和宽度应为match parent
。另外,请给它id
。
现在,在要替换当前布局的片段中,请调用onPause()
和onResume()
。初始化View
中的所有内部容器。并将 visibility
设置为GONE
中的 onResume()
和VISIBLE
中的 onPause()
< /强>
注意:不是您要用此片段替换的FrameLayout
。
假设您ViewPager
中有TabLayout
,ImageView
,<fragment>
和自定义activity_main.xml
。如上所述,添加FrameLayout
。
在abcFragment.java
onClick()
功能中,在addToBackstack(null)
中添加transaction
。
示例代码:
@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);
}
快乐的编码!
答案 6 :(得分:0)
感谢Sapan Diwakar和其他人。这个答案对我有帮助。我只是在其中创建了一个没有片段的RelativeLayout,使用RelativeLayout作为父视图或组视图,指定要替换的事务中的组视图,并且它有效。
代码: 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>
答案 7 :(得分:0)
使用容器而不是使用片段
<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();
请注意,您的片段类应该导入&#39; android.app.Fragment&#39; 确保您使用&#34; support.v4&#34;或者#34;原创&#34;实现,不要混合它们。我遇到了这个问题,因为我把它们混合了。
答案 8 :(得分:0)
您可以使用FragmentTransaction中的setTransition方法来修复重叠问题。
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
答案 9 :(得分: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布局中添加片段,它将始终重叠,因此在运行时使用片段设置初始内容
答案 10 :(得分:0)
使用此问题后我遇到了同样的问题
在你正在替换你的片段
的地方进行框架布局<FrameLayout
android:id="@+id/fragment_place"
android:layout_width="match_parent"
android:layout_height="match_parent" />
和替换代码
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();
如果你想要整个例子,我会发给你评论我......
答案 11 :(得分:0)
我也有同样的问题,但这是因为我没有改变我尝试添加到我的framelayout的片段的背景颜色。
尝试执行此操作,将layout_height
和layout_width
设置为match_parent
答案 12 :(得分:0)
我曾经遇到这个问题,发现这是因为我不小心删除了xml代码中缺少的android:background
属性。我相信它的工作方式就像您在绘画墙壁时一样,android:background
是墙壁将要使用的颜色,而其他视图则放置在该基础颜色之上。当您在放置视图之前不对墙壁进行粉刷时,它们将位于该墙壁已存在的内容之上(对于您而言,就是您的其他片段)。不知道这是否对您有帮助,祝您好运。
答案 13 :(得分:0)
我首先尝试了所有情况,然后尝试解决此问题,但仍未找到解决方案。我不知道为什么它不适合我。我同意以上答案,因为有很多人同意。
我只是在扩展答案,下面是对我有用的方法。
我已在
android:clickable="true"
文件的顶级父级布局中添加了此属性fragment.xml
。
我希望有人能得到帮助。
答案 14 :(得分:0)
var collectionItems= ItemsObservableCollection.Filtering(i=>
!selectedItemsObservableCollection.AnyComputing(y => y.name == i.Name).Value);
将<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">
,应该会有所帮助。
答案 15 :(得分:0)
检查您的框架布局ID并按如下所示替换它
fragmentTransactionChange = MainActivity.this.getSupportFragmentManager().beginTransaction();
fragmentTransactionChange.replace(R.id.progileframe, changeFragment);
fragmentTransactionChange.addToBackStack(null);
fragmentTransactionChange.commit();