Reputation: 9394
I've got an Activity with a DrawerLayout, using the guidelines from http://developer.android.com/training/implementing-navigation/nav-drawer.html.
When I click on an drawerItem, I replace the current view with the new fragment:
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);
Now, sometimes the old fragment is not replaced but the new fragment is placed on top of the old one:
http://img15.imageshack.us/img15/3179/1kqj.png
Why is this, and how to solve this problem?
Relevant 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>
This only happens sometimes, and I haven't found a flow to reproduce this yet. The app doesn't support rotating, so it won't happen there.
Upvotes: 24
Views: 26042
Reputation: 2673
Let's say that you have the root fragment A which you add to a container. Next you add fragment B and you set addToBackStack in the transaction. Lastly you add fragment C but you omit addToBackStack. Now when you press the back button you get these fragments on top of each other.
To recap:
Fragment A is added
Fragment B replaces A with addToBackStack
Fragment C replaces B without addToBackStack
Pressing back results in weird overlaid fragments where A lies on top of C.
You could solve this issue by also adding C to the backStack.
Upvotes: 0
Reputation: 393
I also encounter this issue I found that we are doing a wrong when replacing fragment
private void changeFragment(Fragment targetFragment){
assert getFragmentManager() != null;
getFragmentManager()
.beginTransaction()
.replace(R.id.main_fragment, targetFragment, "fragment")
.setTransitionStyle(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit();
}
this method is replace fragment as other people's code. the reason why fragments are display each other is we define different ID in framelayout in xml. we have to define framelayout IDs(old fragment and new fragment) same.
old framelayout and new framelayout ID in xml for above code should be
<FrameLayout
android:layout_width="match_parent"
android:id="@+id/main_fragment"
android:layout_height="match_parent"/>
Upvotes: 0
Reputation: 2773
I run in this same problem and I see that there's already an accepted answer but these answer is not 100% right and didn't fix my problem. The proposed answer by @Niels removes the views but the fragment(s) is(are) still added. This is what I am using:
/**
* 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();
}
}
}
I am calling this in my onResume to be sure that it will be called also when I navigate back to the fragment.
Upvotes: 0
Reputation: 101
After about 1 week, I found the solution without adding background color or anything else. Just add this code and fix that bullshit. I hope it will help all of you.
@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);
}
Upvotes: 10
Reputation: 9394
We went live with this version and havent received any complaints about this, so I will assume this was the correct answer:
in your onCreateView
method add:
if (container != null) {
container.removeAllViews();
}
Be sure to check if container is not null!
Thanks https://stackoverflow.com/users/2677588/lia-pronina!
Upvotes: 39
Reputation: 59
Add in the every layout
android:background="#FFFFFF"
The layouts background in default are transparen, so just put a background color and the new elements fragment, not display over old fragment
Upvotes: 2
Reputation: 1264
let's try with
fragmentManager.beginTransaction().executePendingTransactions();
after you call commit() method
Upvotes: 0