Андроид - фрагмент.replace() не заменяет содержимое - помещает его сверху
действие:
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
Fragment1 fragment = new Fragment1();
Fragment2 fragment2 = new Fragment2();
transaction.replace(R.id.Fragment1, fragment);
transaction.addToBackStack(null);
transaction.commit();
FragmentTransaction transaction2 = getSupportFragmentManager().beginTransaction();
transaction2.replace(R.id.Fragment1, fragment2);
transaction2.addToBackStack(null);
transaction2.commit();
код в вид:
<fragment
android:id="@+id/Fragment1"
android:name="com.landa.fragment.Fragment1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_below="@+id/include1" />
проблема в том, что контент на самом деле не заменяется - он помещается сверху (поэтому он перекрывается).
когда я нажимаю назад, первый фрагмент отображается правильно (без второго), но изначально оба видны (я хочу, чтобы был виден только последний).
что мне здесь не хватает?
12 ответов:
Вы делаете две вещи неправильно здесь:
вы не можете заменить фрагмент, который статически помещается в макет. Вы должны создать контейнер (например,
FrameLayout) в макете, а затем добавить фрагмент программно с помощьюFragmentTransaction.
FragmentTransaction.replaceожидает идентификатор контейнера, который содержит фрагмент, а не идентификатор фрагмента в качестве первого параметра. Поэтому вы должны передать первый аргумент как идентификатор контейнера, в который вы добавили первый фрагмент.вы можете обратиться к этой ссылке для более подробной информации.
У меня была аналогичная проблема, но моя проблема заключалась в том, что я использовал два разных менеджера фрагментов: Один из getSupportFragmentManager () и один из getFragmentManager (). Если я добавил один фрагмент с SupportFragmentManager, а затем попытался заменить фрагмент на FragmentManager, фрагмент просто добавится сверху. Мне нужно было изменить код, чтобы использовать тот же FragmentManager, и это решило проблему.
сайт разработчика android предлагает использовать
FrameLayoutдля динамической загрузки фрагментов во время выполнения. Вы жестко закодировали фрагмент в своем xml-файле. Поэтому он не может быть удален во время выполнения, как указано в этой ссылке:http://developer.android.com/training/basics/fragments/creating.html
эта ссылка показывает, как добавить фрагменты через программа:
http://developer.android.com/training/basics/fragments/fragment-ui.html
у меня была та же проблема, и я видел все ответы, но ни один из них не содержал моей ошибки! Прежде чем пытаться заменить текущий фрагмент, я показывал фрагмент по умолчанию в xml действия контейнера следующим образом:
<FrameLayout android:id="@+id/fragment_frame_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:layout_width="match_parent" android:layout_height="match_parent" android:name="....ShopFragment" android:id="@+id/fragment" tools:layout="@layout/fragment_shop" /> </FrameLayout>после этого, хотя я проходил мимо
FrameLayoutдоfragmentTransaction.replace()но у меня была такая же проблема. он показывал второй фрагмент поверх предыдущего.проблема устранена путем удаления фрагмента из xml и показывая его программно в
onCreate()метод действия контейнера для предварительного просмотра по умолчанию при запуске программы следующим образом:fragmentTransaction = getFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.fragment_frame_layout,new ShopFragment()); fragmentTransaction.addToBackStack(null); fragmentTransaction.commit();и активность контейнера xml:
<FrameLayout android:id="@+id/fragment_frame_layout" android:layout_width="match_parent" android:layout_height="match_parent">
вы можете очистить backStack перед заменой фрагментов:
FragmentManager fm = getActivity().getSupportFragmentManager(); for (int i = 0; i < fm.getBackStackEntryCount(); i++) { fm.popBackStack(); } // replace your fragments
я согласен с ответом Сапана Дивакара. Но я нашел обходной путь, как это сделать.
во-первых, в вашей деятельности(например,
activity_main), где у вас есть все макеты, добавьтеFrameLayout. Это высота и ширина должны бытьmatch parent. Кроме того, дайте емуid.теперь, в вашем фрагменте, который собирается заменить текущий макет, позвоните
onPause()иonResume(). Инициализируйте все внутренние контейнеры вView. И установить ихvisibilitytoGONEнаonResume()иVISIBLEнаonPause().Примечание: нет
FrameLayoutкоторый вы заменяете этим фрагментом.предположим, что у вас есть
ViewPager,TabLayout,ImageViewи обычай<fragment>наactivity_main.xml. Добавить, аFrameLayoutКак уже упоминалось выше.In
abcFragment.java, в добавьтеaddToBackstack(null)наtransaction.пример кода:
в xyzFragment, который собирается заменить abcFragment (и все, что показано в activity_main.xml), сделайте это
@Override public void onResume() { super.onResume(); // On resume, make everything in activity_main invisible except this fragment. slidingTabs = getActivity().findViewById(R.id.sliding_tabs); viewPager = getActivity().findViewById(R.id.pager); miniPlayerFragment = getActivity().findViewById(R.id.mini_pager); slidingTabs.setVisibility(View.GONE); viewPager.setVisibility(View.GONE); miniPlayerFragment.setVisibility(View.GONE); } @Override public void onPause() { super.onPause(); // Make everything visible again slidingTabs = getActivity().findViewById(R.id.sliding_tabs); viewPager = getActivity().findViewById(R.id.pager); miniPlayerFragment = getActivity().findViewById(R.id.mini_pager); slidingTabs.setVisibility(View.VISIBLE); viewPager.setVisibility(View.VISIBLE); miniPlayerFragment.setVisibility(View.VISIBLE); }удачи в кодировании!
спасибо Сапану Дивакару и другим. Этот ответ помог мне. Я просто создал RelativeLayout без фрагмента внутри него, использовал RelativeLayout в качестве родительского или группового представления, указал это групповое представление в транзакции для замены, и это сработало.
код: getSupportFragmentManager ().beginTransaction() . replace (R. id.content_group_view, itemDetailFragment).commit ();
планировка:
<RelativeLayout android:id="@+id/content_group_view" android:layout_width="match_parent" android:layout_height="match_parent" </RelativeLayout>
используйте контейнер вместо использования фрагмента
<FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:text="Hello World!" />теперь в MainActivity
if(condition) getFragmentManager().beginTransaction().replace(R.id.container,new FirstFragment()).commit(); else getFragmentManager().beginTransaction().replace(R.id.container, new SecondFragment()).commit();обратите внимание, что ваш класс фрагментов должен импортировать 'android.приложение.Фрагмент' Убедитесь, что вы используете "поддержку".v4 " или "оригинальные" реализации и не смешивать их. Я получал эту проблему, потому что я смешал их.
вы можете использовать метод setTransition из FragmentTransaction для устранения проблемы перекрытия.
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
В Oncreate ()
BaseFragmentloginpage fragment = new BaseFragmentloginpage(); android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); fragmentTransaction.replace(R.id.frame, fragment); fragmentTransaction.isAddToBackStackAllowed(); fragmentTransaction.commit();теперь это всегда будет ваш фрагмент по умолчанию ...если вы добавляете фрагмент в XML-макет, он всегда будет перекрываться , поэтому установите начальное содержимое с фрагментом во время выполнения
у меня была такая же проблема после использования эта проблема решена
возьмите макет кадра, где u заменяют фрагмент ur
<FrameLayout android:id="@+id/fragment_place" android:layout_width="match_parent" android:layout_height="match_parent" />и код для замены
public void selectFrag(View view) { Fragment fr; if(view == findViewById(R.id.button2)) { fr = new FragmentTwo(); }else { fr = new FragmentOne(); } FragmentManager fm = getFragmentManager(); FragmentTransaction fragmentTransaction = fm.beginTransaction(); fragmentTransaction.replace(R.id.fragment_place, fr); fragmentTransaction.commit();Если вы хотите весь пример я вышлю вам просто комментировать меня......
у меня также была та же проблема, но это было потому, что я не изменил цвет фона фрагмента, который я пытался добавить в свой framelayout.
попробуйте сделать это с
layout_heightиlayout_widthзначениеmatch_parent
Comments