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();
}
Karakuri
  • 38,365
  • 12
  • 84
  • 104
  • have you looked into `alternative resources`? http://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources – Bill Gary Feb 20 '12 at 23:28
  • 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. – Karakuri Feb 20 '12 at 23:51

4 Answers4

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;
}
Elangovan Manickam
  • 413
  • 1
  • 5
  • 14
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.

KarlKarlsom
  • 5,868
  • 4
  • 29
  • 36
  • 1
    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. – Karakuri Feb 21 '12 at 00:11
  • I know this is an old answer but it has proven helpful. Could you know why FrameLayout presents this issue? – Wilbur Omae Aug 02 '20 at 00:17
5

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

This is a FrameLayout related problem.

Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
Joao Gavazzi
  • 1,818
  • 18
  • 8
2

This works for me.

public void onCreate(Bundle savedInstanceState) {

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

}
Mesop
  • 5,187
  • 4
  • 25
  • 42