Android 碎片相互重叠
我有一个关于抽屉布局的活动,使用来自的指南 当我单击一个DroperItem时,我用新片段替换当前视图:Android 碎片相互重叠,android,android-fragments,Android,Android Fragments,我有一个关于抽屉布局的活动,使用来自的指南 当我单击一个DroperItem时,我用新片段替换当前视图: Fragment fragment; Bundle args = new Bundle(); fragment = new NewsListFragment(); args.putInt("category", position); // Insert the fragment by replacing any existing fragment FragmentManager f
Fragment fragment;
Bundle args = new Bundle();
fragment = new NewsListFragment();
args.putInt("category", position);
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.commit();
mDrawerList.setItemChecked(position, true);
现在,有时旧片段不会被替换,但新片段会被放置在旧片段的顶部:
为什么会这样,如何解决这个问题
相关XML:
<!-- The main content view -->
<LinearLayout
android:id="@+id/rlMain"
android:layout_width="fill_parent"
android:orientation="vertical"
android:layout_height="fill_parent">
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
</FrameLayout>
这只是偶尔发生,我还没有找到一个流程来重现这一点。该应用程序不支持旋转,因此在那里不会发生这种情况。让我们用
fragmentManager.beginTransaction().executePendingTransactions();
在您调用commit()方法之后,我们开始使用此版本,并且没有收到任何对此的投诉,因此我认为这是正确的答案: 在
onCreateView
方法中添加:
if (container != null) {
container.removeAllViews();
}
请确保检查容器是否不为空
谢谢 在每个布局中添加
android:background="#FFFFFF"
默认情况下,布局背景是transparen,因此只需放置背景颜色和新元素片段,而不是显示在旧片段上。大约1周后,我找到了解决方案,而没有添加背景颜色或任何其他内容。只需添加此代码并修复这些废话。我希望它能帮助你们所有人
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
container.clearDisappearingChildren();
return inflater.inflate(R.layout.fragment, container, false);
}
我遇到了同样的问题,我发现已经有了一个被接受的答案,但是这些答案不是100%正确,并且没有解决我的问题。 @Niels提出的答案删除了视图,但仍然添加了片段。 这就是我正在使用的:
/**
* Call this to remove all the other added fragments and keep only the current one.
*
* @param activity the activity to which the fragment has been attached.
* @param fragment the fragment we want to keep.
*/
public static void removeOtherAddedFragments(@NonNull AppCompatActivity activity, @NonNull Fragment fragment) {
FragmentManager fragmentManager = activity.getSupportFragmentManager();
for (Fragment frag : fragmentManager.getFragments()) {
if (frag != null && !frag.equals(fragment) && frag.isAdded()) {
fragmentManager.beginTransaction().remove(frag).commit();
}
}
}
我在我的onResume中调用它,以确保在导航回片段时也会调用它。我也遇到了这个问题,我发现我们在替换片段时出错了
private void changeFragment(Fragment targetFragment){
assert getFragmentManager() != null;
getFragmentManager()
.beginTransaction()
.replace(R.id.main_fragment, targetFragment, "fragment")
.setTransitionStyle(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit();
}
此方法是将片段替换为其他人的代码。片段彼此显示的原因是我们在xml的framelayout中定义了不同的ID。我们必须定义相同的framelayout ID(旧片段和新片段)
上述代码的xml中的旧framelayout和新framelayout ID应为
<FrameLayout
android:layout_width="match_parent"
android:id="@+id/main_fragment"
android:layout_height="match_parent"/>
假设您有根片段A,可以将其添加到容器中。接下来添加片段B,并在事务中设置addToBackStack。最后添加片段C,但忽略addToBackStack。现在,当你按下“后退”按钮时,你会看到这些碎片彼此重叠 重述: 添加片段A 片段B用addToBackStack替换A 片段C替换了不带addToBackStack的B 向后按压会产生奇怪的重叠碎片,其中A位于C的顶部
您还可以通过在backbackback中添加C来解决此问题。Fragment;Bundle args=新Bundle();fragment=新的NewsListFragment();参数putInt(“类别”,位置);//通过替换任何现有片段FragmentManager FragmentManager=getSupportFragmentManager()插入片段;fragmentManager.beginTransaction().replace(R.id.content_frame,fragment).addToBackStack(null.commit();mDrawerList.setItemChecked(位置,true);请粘贴您的xml好吗?请尝试使用
container.removeAllViews()代码>在onCreateView
方法中“有时”是什么意思?当您不处理活动的重新创建时,通常会在屏幕旋转时发生这种情况。或者即使不旋转屏幕也会发生这种情况?我发现这种行为的模式是:用新片段替换当前容器,然后用第一个片段的新实例再次替换。在我的例子中,在我的ListFragment
上,我会打开一个DetailFragment
,然后在抽屉布局中单击另一个条目,再次打开ListFragment
。确保测试后退按钮的行为,因为它可能引用了backbackbackback上的旧片段。如果是,请使用getActivity().getFragmentManager().popBackStack()
在另一个片段上显示新片段时,是否可以调用fragmentTransaction.replace()而不是add()?我是这样做的,但问题出在后面的导航中。如果您有:1/添加2/替换B(不要继续后退)3/替换C(继续后退)4/返回,您可能会遇到问题。这是安卓系统的一个bug:replace是“删除/隐藏并添加”而不是“删除并添加”,一旦添加了新的一个,另一个将留在后面…我同意这完全是胡说八道,但这在我的情况下不起作用-removeAllViews()的答案起作用了-这是一个完全的笑话-我们需要跳过这一关。