Фрагменты Android перекрываются после поворота экрана - PullRequest
9 голосов
/ 21 февраля 2012

Это приложение является обучающим упражнением для меня, среди прочего, с использованием фрагментов. У этого есть единственное действие, которое управляет некоторыми различными фрагментами. Первый - это ListFragment (A), который показывает, когда приложение запускается и загружает элементы списка из курсора. Щелчок по элементу списка уведомляет действие о замене ListFragment на DetailFragment (B) для этого элемента. Если, глядя на (B), я поворачиваю экран, я вижу (B) поверх (A), например:

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

По-моему, это связано с тем, что Android уничтожает и воссоздает действие при изменении конфигурации. Мне интересно, что является самым чистым решением этой проблемы. Далее следуют некоторые фрагменты кода, дайте мне знать, если есть что-то еще, что я должен опубликовать.

Рез / макет / 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();
}

Ответы [ 4 ]

11 голосов
/ 31 января 2016

Согласно Android dev page , в методе Activity onCreate вы должны проверить, имеет ли значение saveInstanceState значение NULL, прежде чем добавлять фрагмент в действие.Фрагмент кода метода onCreate Activity из этой страницы утверждает, что.

// 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;
}
5 голосов
/ 21 февраля 2012

Это потому, что вы используете макет рамы в качестве контейнера.Это не будет совпадать с другими макетами.

И для достижения наилучшей практики, вы должны сделать XML-файл в вашем макете / папке, где используется только ваш фрагмент списка.В вашей компоновке / вы помещаете XML-файл с обоими использованными и упорядоченными фрагментами.

Затем система обрабатывает все создание.фрагменты.И ваша активность в основном сводится к вызову setContentView ().

При нажатии на элемент списка вы затем проверяете с помощью диспетчера фрагментов, создан ли ваш фрагмент сведений.Если он создан, вы вызываете публичную функцию в подробном фрагменте для установки данных.

Если он не создан, вы создаете намерение с новым действием.

Я знаю 2 хороших урока: страница фрагментов на странице разработчиков android и vogella.de оба предоставят вамподробный пример / учебник.

3 голосов
/ 18 декабря 2013

Измените FrameLayout для LinerLayout, и проблема будет решена.

Это проблема, связанная с FrameLayout.

2 голосов
/ 12 июля 2012

Это работает для меня.

public void onCreate(Bundle savedInstanceState) {

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

}
...