Android fragments overlapping after screen rotation
Asked Answered
B

4

11

This app is a learning exercise for me using fragments, among other things. It has a single activity that manages some different fragments. The first is a ListFragment (A), which shows when the app starts and loads list items from a cursor. Clicking a list item notifies the activity to replace the ListFragment with a DetailFragment (B) for that item. If while looking at (B) I rotate the screen, I see (B) on top of (A), like this:

http://postimage.org/image/uhy016ds7/

My best guess is it has to do with Android destroying and re-creating the activity on a configuration change. I am wondering what is the cleanest solution for this problem. Some code snippets follow, let me know if there's something else I should post.

res/layout/home.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <fragment
        android:id="@+id/fragment_place_list"
        android:name="com.simbiosys.apps.foodfast.ui.PlaceListFragment"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </fragment>
</FrameLayout>

MyActivity.onCreate

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.home);

    placeListFragment = (PlaceListFragment) getSupportFragmentManager().findFragmentById(
            R.id.fragment_place_list);

}

MyActivity.showDetailPane

public void showDetailPane(String id, String reference) {
    placeDetailFragment = PlaceDetailFragment.newInstance(id, reference);
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction ft = fragmentManager.beginTransaction();
    ft.addToBackStack(null);
    ft.hide(placeListFragment);
    ft.replace(R.id.fragment_container, placeDetailFragment);
    ft.show(placeDetailFragment);
    ft.commit();
}
Barnacle answered 20/2, 2012 at 23:24 Comment(2)
have you looked into alternative resources? developer.android.com/guide/topics/resources/…Tajuanatak
Well, I'm focusing on phone screens at the moment. The layout for the ListFragment wouldn't be any different in landscape anyway. In fact, there is no layout xml for the ListFragment since all it currently has is the built-in ListView.Barnacle
F
6

It is because you use a frame layout as container. It wouldn't be overlapping for other layouts.

And for what you want to achieve best practice is to make a XML file into your layout/ folder where only your listfragment is used. In your layout-land/ you put a XML file with both fragments used and arranged.

Then the system handles all the creation of the. fragments. And your activity basically reduces to a setContentView() call.

On a list item click you then check with the fragment manager whether or not your detail fragment is created. If it is created you your call a public function within the detail fragment to set the data.

If it is not created, you create a intent with a new activity.

I know 2 good tutorials: the fragments page on the android developers page and vogella.de both will give you a detailed example/tutorial.

Forecourse answered 20/2, 2012 at 23:50 Comment(2)
Thanks for pointing out that it was the FrameLayout. However, I'm trying not to start another activity as this one is doing some other behind-the-scenes work. That said, you have given me one or two ideas to work around, so thanks.Barnacle
I know this is an old answer but it has proven helpful. Could you know why FrameLayout presents this issue?Birthwort
B
12

As per Android dev page, in Activity's onCreate method you should check if the savedInstanceState is null before adding the fragment to the activity. Code snippet of onCreate method of Activity from this page states that.

// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
     return;
}
Bucaramanga answered 31/1, 2016 at 17:43 Comment(2)
Thanks, works perfectly, saved me after 2 hrs of struggling with itKristine
Also note that this guide uses a FrameLayout.Beuthen
F
6

It is because you use a frame layout as container. It wouldn't be overlapping for other layouts.

And for what you want to achieve best practice is to make a XML file into your layout/ folder where only your listfragment is used. In your layout-land/ you put a XML file with both fragments used and arranged.

Then the system handles all the creation of the. fragments. And your activity basically reduces to a setContentView() call.

On a list item click you then check with the fragment manager whether or not your detail fragment is created. If it is created you your call a public function within the detail fragment to set the data.

If it is not created, you create a intent with a new activity.

I know 2 good tutorials: the fragments page on the android developers page and vogella.de both will give you a detailed example/tutorial.

Forecourse answered 20/2, 2012 at 23:50 Comment(2)
Thanks for pointing out that it was the FrameLayout. However, I'm trying not to start another activity as this one is doing some other behind-the-scenes work. That said, you have given me one or two ideas to work around, so thanks.Barnacle
I know this is an old answer but it has proven helpful. Could you know why FrameLayout presents this issue?Birthwort
F
5

Change the FrameLayout for LinerLayout and the problem will be solved.

This is a FrameLayout related problem.

Fiance answered 18/12, 2013 at 3:50 Comment(0)
P
2

This works for me.

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    ....
    fragment = getFragmentManager().findFragmentByTag(TAG);
    if(fragment == null) fragment = new Fragment();
    ....

}
Psychogenic answered 12/7, 2012 at 10:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.