سؤال

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();
}
هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

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

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

This is a FrameLayout related problem.

This works for me.

public void onCreate(Bundle savedInstanceState) {

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

}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top