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" />
问题是,内容并没有真正被取代 – 它被放在顶部(所以它重叠)。
当我点击后,第一个片段得到正确显示(没有第二个),但最初都是可见的(我只希望最后一个可见)。
我在这里错过了什么?
你在这里做了两件事:
-
您无法replace静态放置在
xml
布局文件中的片段。 您应该在布局中创build一个容器(例如一个FrameLayout
),然后使用FragmentTransaction
以编程方式添加FragmentTransaction
。 -
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
。
假设你在ViewPager
有ViewPager
, TabLayout
, ImageView
和一个自定义的<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布局中添加片段,它将总是重叠,所以在运行时设置片段的初始内容
使用此问题后,我解决了同样的问题
-
采取框架布局,你正在取代你的片段
<FrameLayout android:id="@+id/fragment_place" android:layout_width="match_parent" android:layout_height="match_parent" />
-
和代码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();
如果你想要整个例子,我会给你发个简单的评论……