23

我有一个带有 DrawerLayout 的 Activity,使用来自http://developer.android.com/training/implementing-navigation/nav-drawer.html的指南。

当我单击一个drawerItem 时,我将当前视图替换为新片段:

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

现在,有时旧片段没有被替换,但新片段被放置在旧片段之上:

http://img15.imageshack.us/img15/3179/1kqj.png

为什么会这样,以及如何解决这个问题?

相关的 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>

这只有时会发生,我还没有找到重现这种情况的流程。该应用程序不支持旋转,因此不会在那里发生。

4

7 回答 7

39

我们使用这个版本并没有收到任何投诉,所以我认为这是正确的答案:

在您的onCreateView方法中添加:

if (container != null) {
    container.removeAllViews();
}

一定要检查容器是否不为空!

谢谢https://stackoverflow.com/users/2677588/lia-pronina

于 2013-08-22T08:02:07.467 回答
10

大约 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);
}
于 2016-03-08T05:17:43.373 回答
2

添加每个布局

android:background="#FFFFFF"

默认的布局背景是透明的,所以只需放置背景颜色和新元素片段,而不是显示在旧片段上

于 2015-01-28T19:03:14.263 回答
0

让我们试试

fragmentManager.beginTransaction().executePendingTransactions();

在你调用 commit() 方法之后

于 2013-08-19T08:58:29.470 回答
0

我遇到了同样的问题,我看到已经有一个公认的答案,但这些答案不是 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 中调用它以确保当我导航回片段时它也会被调用。

于 2016-03-11T10:27:39.603 回答
0

我也遇到这个问题我发现替换fragment时我们做错了

 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。我们必须定义相同的框架布局 ID(旧片段和新片段)。

上述代码的 xml 中的旧框架布局和新框架布局 ID 应该是

 <FrameLayout
        android:layout_width="match_parent"
        android:id="@+id/main_fragment"
        android:layout_height="match_parent"/>
于 2021-04-05T13:16:49.977 回答
0

假设您将根片段 A 添加到容器中。接下来,您添加片段 B 并在事务中设置 addToBackStack。最后你添加了片段 C,但你省略了 addToBackStack。现在,当您按下后退按钮时,您会看到这些片段彼此重叠。

回顾一下:

添加了片段 A

片段 B 用 addToBackStack 替换 A

片段 C 在没有 addToBackStack 的情况下替换 B

向后按会导致奇怪的重叠片段,其中 A 位于 C 之上。

您也可以通过将 C 添加到 backStack 来解决此问题。

于 2021-04-09T20:53:38.460 回答