Андроид - фрагмент.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" />


проблема в том, что контент на самом деле не заменяется - он помещается сверху (поэтому он перекрывается).



когда я нажимаю назад, первый фрагмент отображается правильно (без второго), но изначально оба видны (я хочу, чтобы был виден только последний).



что мне здесь не хватает?

1090   12  

12 ответов:

Вы делаете две вещи неправильно здесь:

  1. вы не можете заменить фрагмент, который статически помещается в макет. Вы должны создать контейнер (например,FrameLayout) в макете, а затем добавить фрагмент программно с помощью FragmentTransaction.

  2. 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. И установить их visibility to GONE на 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-макет, он всегда будет перекрываться , поэтому установите начальное содержимое с фрагментом во время выполнения

у меня была такая же проблема после использования эта проблема решена

  1. возьмите макет кадра, где u заменяют фрагмент ur

    <FrameLayout
                    android:id="@+id/fragment_place"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />
    
  2. и код для замены

    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

    Ничего не найдено.