У чому різниця між getSupportFragmentManager () та getChildFragmentManager ()?


78

Мій клас успадковує Fragment, і тому він не може використовувати getSupportFragmentManager (). Я використовую getChildFragmentManager, і він показує мені Помилка - IllegalArguementException: Не знайдено подання для помилки id ...

Будь-яке керівництво буде вдячне.

Код для виклику AttachmentsListFragment:

Bundle b = new Bundle();
b.putSerializable("AttachmentsList", msg.attachments);  
        AttachmentListFragment listfrag = new AttachmentListFragment(msg.attachments);
FragmentTransaction transaction = getFragmentManager().beginTransaction();       
transaction.add(R.id.attachmentslistcontainer, listfrag);
transaction.addToBackStack(null);
transaction.commit();

attachmentslayout.xml є

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/attachmentslistcontainer"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textViewAttachmentHeader"
        style="@style/Normal.Header.Toolbar"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/list_separator_background"
        android:ellipsize="end"
        android:gravity="center"
        android:maxLines="2"
        android:text="@string/attachments_header"
        android:textColor="#FFFFFFFF"
        android:textSize="22sp"
        android:textStyle="bold"
        android:visibility="visible" />

    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    </ListView>

</FrameLayout>

AttachmentsListFragment.java

public class AttachmentListFragment extends ListFragment implements IAttachmentsData {

    ArrayList<Attachments> items = null;
    Integer cellLayoutID;
    Integer index;

    public AttachmentListFragment() {

    }

    public AttachmentListFragment(ArrayList<Attachments> items) {
        this.items = items;
        Log.i("Logging", "Items size" + items.size()); //$NON-NLS-1$
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle bundle;
        if (savedInstanceState != null) {
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        //super.onCreateView(inflater, container, savedInstanceState);

        //  setContentView(R.layout.attachmentslayout);
        View view = inflater.inflate(R.layout.attachmentslayout, container, false);
        return view;
    }


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setListAdapter(new AttachmentAdapter(
                getActivity().getApplicationContext(),
                R.layout.attachmentslistcellcontent,
                items));
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // TODO Auto-generated method stub
        super.onListItemClick(l, v, position, id);
        index = position;
        Intent intent = new Intent();
        Bundle b = new Bundle();
        b.putByteArray("Data", items.get(position).getImageData());
        intent.putExtras(b);
    }


    public byte[] getData() {
        // TODO Auto-generated method stub
        if (items != null && index < items.size()) {

            return items.get(index).getImageData();
        }
            return null;
    }

}

2
Будь ласка, опублікуйте весь метод та / або клас, де ви викликаєте "getChildFragmentManager".
WindyB

Відповіді:


154

Визначення getChildFragmentManager():

Поверніть приватний FragmentManager для розміщення та управління фрагментами всередині цього фрагмента.

Тим часом визначення getFragmentManager()(або в даному випадку getSupportFragmentManager()) є:

Поверніть FragmentManager для взаємодії з фрагментами, пов’язаними з діяльністю цього фрагмента.

По суті, різниця полягає в тому, що Фрагменти тепер мають власні внутрішні елементи, FragmentManagerякі можуть обробляти Фрагменти. Дочірній FragmentManager - це той, який обробляє фрагменти, що містяться лише у фрагменті, до якого він був доданий. Інший FragmentManager міститься в цілому Activity.

У цьому випадку я здогадуюсь, що ви додали фрагменти до FragmentManager Activity. Ви отримуєте дочірній FragmentManager, який не містить того, що ви шукаєте. Таким чином, ви отримуєте виняток, оскільки він не може знайти фрагмент із заданим ідентифікатором, оскільки він знаходиться в іншому FragmentManager.


3
Я спробував використовувати getChildFragmentManager. Але він також показує той самий виняток
NinjaCoder

1
Я думав, ви сказали, що вже використовуєте getChildFragmentManager.
DeeV

якщо я використовую getSupportFragmentManager для створення дочірнього фрагмента, щоб батько містив дочірній матеріал, і обидва вони були видимими / на передньому плані, що робить кнопка "Назад"? це вискакує з батьків? чи дитина? тощо?
lv99Zubat

1
@Rai getSupportFragmentManagerі getFragmentManagerобидва менеджери фрагментів на найвищому рівні Activity. Фрагмент, який ви технічно додаєте, не є "дочірнім фрагментом" за визначенням, описаним тут. Вони є Фрагментами, якими обробляється Діяльність. Будь-який Фрагмент, який Ви опублікуєте на задньому плані будь-якого менеджера, яким обробляється Діяльність, буде видалений на "назад".
DeeV

25

getFragmentManagerналежати Activity
getChildFragmentManagerналежатиFragment

Приклад у нас є додаток , яке є MainActivity, Fragment1, Fragment2, container_view_on_mainє розташування вactivty_main.xml

Для відображення Fragment1 на MainActivityми повинні використовуватиgetSupportFragmentManager()

getSupportFragmentManager().beginTransaction().replace(R.id.container_view_on_main, Fragment1.newInstance());

Для відображення Fragment2 у Fragment1нас є 2 способи

ВИКОРИСТАННЯ getFragmentManager()

getFragmentManager().beginTransaction().replace(R.id.container_view_on_main, Fragment1.newInstance());

ВИКОРИСТАННЯ getChildFragmentManager()

Спочатку нам потрібно створити макет із ідентифікатором container_view_on_fragment1всередині fragment1.xml, потім

getChildFragmentManager().beginTransaction().replace(R.id.container_view_on_fragment1, Fragment2.newInstance()).commit();

ВИСНОВОК

У цій демонстрації, я думаю, нам слід використовувати, getFragmentManager()коли переходимо від Fragment1до, Fragment2тому що це просто і добре для роботи ( Fragment1зупиниться, коли Fragment2відкриється)

Коли ми використовуємо getChildFragmentManager()?
Наприклад, у вас MainActivityє ViewPagerякі мають 3 сторінки, всередині кожної сторінки вам потрібно замінити якийсь фрагмент.

БІЛЬШЕ
- getParentFragment ()
getFragmentManager() => return null
getChildFragmentManager() => завжди повертає кореневий фрагмент ( Fragment1у демонстрації навіть ми переходимо до Fragment3 ,, ...)

Ця відповідь базується на моєму розумінні, тому, будь ласка, виправте мене, якщо я помиляюся. Сподіваюся, це допоможе


2

Якщо ви хочете мати фрагмент, який поводиться як контейнер фрагментів, ви повинні використовувати метод getChildFragmentManager фрагмента. Якщо ви використовуєте getSupportFragmentManager, ви в основному будете використовувати менеджер фрагментів, який поводиться так, як проходить життєвий цикл діяльності, а не так, як робить ваш фрагмент.

Наприклад, у мене був фрагмент, який містив ViewPager - він називається CollectionsFragment. Тож у мене було 3 фрагменти, відображені у ньому як вкладки: AllCollectionsFragment, MyCollectionsFragment, FavouriteCollectionsFragment. І я передав getActivity (). GetSupportFragmentManager () в FragmentStatePagerAdapter, яким я користувався.

Отже, це спричинило наступну поведінку - методи onDestroyView / onDestroy / onDetach / onStop фрагментів 3 вкладок не можна було викликати. Коли я змінив використання getChildFragmentManager, все було нормально.

Якщо ви хочете, ви можете перевірити документи на два методи:

getChildFragmentManager (): Повернення приватного FragmentManager для розміщення та управління фрагментами всередині цього фрагмента.

getSupportFragmentManager (): повертає FragmentManager для взаємодії з фрагментами, пов'язаними з діяльністю цього фрагмента.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.