В чем разница между getSupportFragmentManager() и getChildFragmentManager()?

Мой класс наследует Fragment и поэтому не может использовать getSupportFragmentManager(). Я использую getChildFragmentManager, и он показывает мне Error - 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;
    }

}

Ответ 1

Определение getChildFragmentManager():

Возвращает частный FragmentManager для размещения и управления фрагментами внутри этого фрагмента.

Между тем определение getFragmentManager() (или в этом случае getSupportFragmentManager()):

Вернуть FragmentManager для взаимодействия с связанными фрагментами с этой активностью фрагмента.

В основном разница заключается в том, что Fragment теперь имеет свой собственный внутренний FragmentManager, который может обрабатывать фрагменты. Ребенок FragmentManager - это тот, который обрабатывает фрагменты, содержащиеся только в Фрагменте, к которому он был добавлен. Другой FragmentManager содержится во всем Activity.

В этом случае я предполагаю, что вы добавили фрагменты в Activity FragmentManager. Вы получаете дочерний FragmentManager, который не содержит того, что вы ищете. Таким образом, вы получаете исключение, потому что он не может найти Фрагмент с данным идентификатором, потому что он находится в другом FragmentManager.

Ответ 2

getFragmentManager принадлежат Activity
getChildFragmentManager принадлежит к Fragment

Пример у нас есть приложение, которое имеет MainActivity, Fragment1, Fragment2, container_view_on_main - это макет в activty_main.xml

MainActivity отобразить Fragment1 в MainActivity мы должны использовать getSupportFragmentManager()

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

Для отображения Fragment2 из Fragment1 у нас есть 2 пути

USE getFragmentManager()

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

USE getChildFragmentManager()

Сначала мы должны создать макет с идентификатором container_view_on_fragment1 fragment1.xml, затем

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

ЗАКЛЮЧЕНИЕ

В этой демонстрации я думаю, что мы должны использовать getFragmentManager() при getFragmentManager() от Fragment1 к Fragment2 потому что он прост и хорош для производительности (Fragment1 остановится, когда Fragment2 откроется)

Когда мы используем getChildFragmentManager()?
Например, у вашей MainActivity есть ViewPager который имеет 3 страницы, внутри каждой страницы вам нужно заменить какой-то фрагмент.

БОЛЬШЕ
- getParentFragment()
getFragmentManager() => вернуть getFragmentManager()
getChildFragmentManager() => всегда возвращать корневой фрагмент (Fragment1 в демоверсии, даже если мы переходим к Fragment3 ,...)

Этот ответ основан на моем понимании, поэтому, пожалуйста, поправьте меня, если я ошибаюсь. Надеюсь, это поможет

Ответ 3

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

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

Таким образом, это вызывало следующее поведение - методы onDestroyView/onDestroy/onDetach/onStop для трех фрагментов вкладок не вызывались. Когда я перешел на использование getChildFragmentManager, все было в порядке.

Если вы хотите, вы можете проверить документы для двух методов:

getChildFragmentManager(): Возвращает частный FragmentManager для размещения и управления фрагментами внутри этого фрагмента.

getSupportFragmentManager(): Возвращает FragmentManager для взаимодействия с фрагментами, связанными с этим действием фрагментов.