我使用http://developer.android.com/training/implementing-navigation/nav-drawer.html中的指南获得了一个带有DrawerLayout的活动。
当我点击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>
这种情况有时会发生,我还没有找到重现这一点的流程。该应用程序不支持旋转,所以它不会发生在那里。
答案 0 :(得分:25)
我们上传了这个版本,并没有收到任何关于此的投诉,所以我认为这是正确的答案:
在onCreateView
方法中添加:
if (container != null) {
container.removeAllViews();
}
请务必检查容器是否为空!
答案 1 :(得分: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);
}
答案 2 :(得分:1)
添加每个布局
android:background="#FFFFFF"
默认情况下布局背景是透明的,所以只需将背景颜色和新元素片段放在一起,而不是显示在旧片段上
答案 3 :(得分:0)
让我们试试
fragmentManager.beginTransaction().executePendingTransactions();
调用commit()方法
之后答案 4 :(得分: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中调用它,以确保在导航回片段时也会调用它。
答案 5 :(得分: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"/>
答案 6 :(得分:0)
假设您将根片段 A 添加到容器中。接下来添加片段 B 并在事务中设置 addToBackStack。最后添加片段 C,但省略 addToBackStack。现在,当您按下后退按钮时,这些片段会叠在一起。
总结:
添加片段A
片段 B 用 addToBackStack 替换 A
Fragment C 在没有 addToBackStack 的情况下替换了 B
按回导致奇怪的重叠片段,其中 A 位于 C 之上。
你也可以通过在 backStack 中添加 C 来解决这个问题。