Android 碎片相互重叠

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

我有一个关于抽屉布局的活动,使用来自的指南

当我单击一个DroperItem时,我用新片段替换当前视图:

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()的答案起作用了-这是一个完全的笑话-我们需要跳过这一关。